docs
/
EventOxygen

Data models

The event, ticket, session and participant records, the community records behind the feed and chat, and the rules the server enforces on each.

Schemas live in the SDK at sdk/src/models/events/ and sdk/src/models/community/. Every record is a BaseModel envelope — { sk, name, datatype, data, owner, createdate, modifydate }; fields below are inside data. The app keeps only two Dart models (UserModel, AuthResponse) and treats everything else as maps.

Events are addressed by slug and by id

The app navigates with the event's data.name (the slug), while sessions, participants and tickets reference the event by its sk. The client service resolves either form before querying, and EventProvider merges ticket groups by the fetched sk. Any new event-scoped query must go through the same resolution or it returns nothing for slug callers.

Events

event — title; slug (unique, ^[a-z0-9-]+$); type (default conference); status: draft, published, live, completed, cancelled; startDate/endDate, startTime/endTime, timezone (default America/New_York); days[] {date, label, startTime, endTime}; tracks[] {id, name, color, location}; venue (an object {name, address, city, country} — the app joins it to a string), address {street1, street2, city, region, postalCode, country}; zones[] {id, name, capacity}; scanPoints[] {name, zone, acceptedTicketTypes[], scanType: entrance | eligibility, matchBy}; accreditationPoints[] {name, ticketTypes[], allowWalkIn, allowOnlinePickup}; settings {networkingEnabled, leadsEnabled, checkInRequired, qrRotationEnabled, qrRotationInterval (30 s), allowWalkIns, requireApproval, maxAttendeesPerSession}; coverImage, images[]; stats {totalTicketsSold, totalRevenue, totalAttendees, totalSessions, totalParticipants}.

event_session — event (sk); title; type: talk, panel, workshop, keynote, networking, break, meetup, other; status: draft, scheduled, live, completed, cancelled; day (date), startTime/endTime (wall clock strings such as 19:00), duration; track, zone, room; participants[]; capacity, registeredCount, attendedCount, waitlistCount; requiredAccreditation[], requiredTicketTypes[], isPublic; streaming {}, resources[], feedbackEnabled, averageRating. The schedule buckets by day.

event_ticket_type — event; title, slug, color; price (0), currency (USD); capacity, soldCount; saleStartDate/saleEndDate; isActive; maxPerOrder (10), maxPerCustomer (defaults to 1 when the price is 0); allowReentry (false), reentryLimit; allowTransfer (false), transferDeadline, transferPreservesPerks (true); zoneAccess[], sessionAccess[]; perks[].

event_booking — the purchase. event, email, holderName, phone; status: pending, paid, confirmed, cancelled, refunded, expired; items[], ticketCount, subtotal, discount, tax, total, currency, promoCode; payment {method: stripe | paypal | card | cash | free | other, status}; bookingRef (9 random upper-case characters); confirmedAt, cancelledAt, expiresAt. Free or already-paid bookings issue tickets immediately; otherwise the booking waits as pending until confirm.

event_ticket — name is the 12-character ticket id; event, ticketType; holder, holderEmail, holderName; status: pending, confirmed, checked_in, cancelled, refunded, transferred; code, codeSecret (hidden), codeLastRotated; badgePrinted; fulfilledAt, fulfilledBy, accreditationPoint; perks[] with claims[]; checkIns[] {zone, timestamp, direction, validator, scanPointId}, lastCheckIn, currentZone; purchase {bookingId, transactionId, amount, currency, purchasedAt, paymentMethod}; transfers[] {fromHolder, toHolder, transferredAt, reason}.

The QR payload is ticketId:timestamp:signature (HMAC-SHA256, 16-character signature) with a 60-second default validity, which is why the wallet fetches GET /client/events/tickets/:id/qr for a fresh one rather than caching it. Fulfilment and transfer rotate codeSecret; a forwarded screenshot therefore dies the moment the ticket is transferred.

event_participant — event, customer, email; type: attendee, speaker, exhibitor, sponsor, volunteer, press, vip (free string in practice); role; status: invited, accepted, declined, waitlisted, confirmed, cancelled, no_show; featured; sessions[] (session ids — the profile page resolves them to titles); bio, shortBio, image; social {linkedin, twitter, website, github}; topics[], tags[]; logistics {}, rsvp {}.

event_checkin — one record per scan, including denials: event, ticket, attendee, direction, zone, checkpoint, timestamp, validatedBy, validatorDevice, validationMethod, scanType, status: success, denied, flagged, override; denialReason.

Community

community_post — author plus authorInfo {firstName, lastName, image, company}; page, pageName; content; contentType: text, image, video, link, poll, article, share; media[], link {}; poll {options[{id, text, votes, voters[]}], totalVotes, allowMultiple, endsAt}; hashtags[], mentions[] (extracted on the server); visibility: public, page, connections, private; sharedPost, shareComment (a repost is a new post of type share pointing at the original); pinned, edited; stats {reactions, comments, shares, views}; reactionSummary {like: n, …}; status: active, flagged, removed, draft.

The feed stamps two viewer fields when the request carries the customer token: viewerLiked (from community_reaction where reactor is the caller) and viewerSaved (from community_bookmark where owner is the caller).

community_comment — post, author, authorInfo, content, parentComment (threading), media[], stats {reactions, replies}, status. Deleting is a soft removed with the post's counter decremented.

community_reaction — target, targetType: post, comment, story, message; reactor; type: like, love, fire, clap, insightful, funny, sad, angry. One record per reactor and target. POST /client/community/react toggles: the same type again removes it, a different type changes it. Send like to un-like; sending unlike creates a new reaction type.

community_bookmark — owner, target, targetType: post, event, session, page, person, comment, story; collection, notes. Idempotent per owner and target.

community_connection — requester/requesterEmail/requesterInfo, target/targetEmail/targetInfo; status: pending, accepted, rejected, blocked, cancelled; context {type: event | qr_scan | search | recommendation | mutual | other}; message; requestedAt, respondedAt. Matching is by email in both directions; a request is refused when a pending, accepted or blocked record already exists.

community_message — thread is deterministic and symmetric: thread_<a>_<b> with the two emails sorted; sender, senderInfo, recipient; content, contentType: text, image, file, audio, link, contact; attachments[]; status: sent, delivered, read, deleted; replyTo; deletedBySender, deletedByRecipient. Sending checks the recipient exists and that neither side has blocked the other. Group chats use community_group_chat.

community_meeting — title; organizer; participants[] {…, status: pending | accepted | declined | tentative}; startTime, endTime, duration, timezone; locationType: in_person, virtual, phone; location, meetingLink; event; status: proposed, confirmed, cancelled, completed, no_show. A meeting becomes confirmed only when every participant has accepted; rescheduling resets everyone to pending and the meeting to proposed. "Upcoming" lists confirmed meetings only.

community_notification — recipient, recipientEmail; type from connection_request, connection_accepted, message, reaction, comment, mention, share, follow, page_invite, announcement, event_reminder, session_starting, meeting_invite, meeting_reminder, system and a few more; actor, actorInfo; target, targetType; summary; groupKey; read, readAt; pushed, pushChannel: fcm, apns, web, email. The demo organization has none of these records, so the Notifications tab is legitimately empty there.

Also present: community_story (24-hour stories with expiresAt, stickers, view counts), community_follow (follower, following, followingType: person, page, hashtag), community_page (the per-event community page the feed is scoped to; found with GET /client/community/pages?type=event).

Customer

customer is the identity everywhere in the community: email is the key used by connections, threads and reactions. Other fields the app reads or writes: firstName, lastName, phone, company, jobTitle, bio, image (string or {url}), address {city, country}, interests[], social {}, groups[] (used as roles when roles is absent). UserModel unwraps the data envelope and accepts customer or user as the root key of an auth response.