Reduced MVP

Rizi technical documentation, architecture, API details, and diagrams

This site consolidates the current reduced-scope RiziEvents documentation in one protected place, including Mermaid diagrams, sequence flows, QA planning, and the formal technical rationale for the MVP.

Next.js + Vercel Supabase backend Google Maps venue support Offline payment only

Section

Technical Documentation

RiziEvents Technical Documentation

1. Project Summary

RiziEvents is a reduced MVP for event publishing and registration. The documented product scope is intentionally limited to the features needed for a phase-three academic review and for a small four-member student team.

The platform allows an organizer to sign in, create an event, publish it under a slug-based public URL, accept guest registrations, and manage offline check-in at the venue. The official MVP architecture uses Next.js on Vercel for the web application and Supabase for authentication, database, and backend platform services.

Official URLs

  • Canonical production URL: https://www.rizi.app
  • Production apex redirect: https://rizi.app
  • Staging environment: https://staging.rizi.app
  • Public event page pattern: https://www.rizi.app/e/[slug]

2. MVP Scope

In scope

  • Organizer authentication
  • Event creation and editing
  • Event publishing
  • Public event landing page
  • Guest registration
  • Guest list viewing
  • Offline/manual guest check-in
  • Venue location selection using Google Maps API and Places SDK

Out of scope

  • Online payment gateways
  • Premium subscriptions and monetization
  • Custom domains and subdomains
  • White-label branding
  • Developer API exposure beyond the documented internal endpoints
  • Advanced analytics and platform administration features
  • Marketplace-style modules
  • AI-assisted content generation as an official MVP capability

3. User Stories and Priority

Must Have

  • As an organizer, I want to create an account and sign in, so that I can manage my events securely.
  • As an organizer, I want to create an event with its title, date, venue, and capacity, so that I can publish it for guests.
  • As an organizer, I want to publish an event to a public URL, so that guests can access the event page.
  • As a guest, I want to open the public event page, so that I can learn about the event details.
  • As a guest, I want to register for the event, so that I can reserve my place.
  • As an organizer, I want to see the registered guest list, so that I can manage attendance.
  • As an organizer, I want to check in guests manually at the venue, so that I can track who attended.

Should Have

  • As an organizer, I want to add agenda items, so that guests can understand the event schedule.
  • As an organizer, I want to add speakers, so that the event page looks complete and informative.
  • As a guest, I want venue directions from Google Maps, so that I can reach the location easily.

Could Have

  • As an organizer, I want lightweight brand customization, so that each event page matches the event identity.
  • As a guest, I want a clearer registration confirmation experience, so that I know my registration was received.

Won't Have in This MVP

  • As an organizer, I want to accept online payments, so that I can sell tickets online.
  • As an organizer, I want to attach a custom domain, so that my event uses a branded URL.
  • As a team owner, I want advanced roles, plans, and monetization controls, so that I can manage a commercial platform.

4. Mockups

Mockups and user-story drafts were completed earlier by the team and are reused as the visual basis for this submission. The expected main screens covered by those mockups are:

  • Organizer sign in and sign up
  • Organizer dashboard
  • Create/edit event form
  • Public event landing page
  • Guest registration form
  • Guest list
  • Offline/manual check-in screen

Organizer Mockups

The organizer journey mockup currently covers the organizer-side flow for sign in, dashboard access, event creation and editing, publication readiness, and organizer event management.

Direct Figma embed link: https://embed.figma.com/design/RmJ2tLT6Nm2U7oc9pciS2j/Rizi-Final-Mockup?node-id=15-259&embed-host=share

Visitor Mockups

The visitor journey mockup currently covers the guest-facing flow for opening the event page, reviewing the public event details, and completing the registration journey.

Direct Figma embed link: https://embed.figma.com/design/RmJ2tLT6Nm2U7oc9pciS2j/Rizi-Final-Mockup?node-id=4-2111&embed-host=share

This repository focuses on the technical documentation and architecture that align with those mockups.

5. System Architecture

The high-level architecture is documented in the GitHub repository: system-architecture.mmd

GitHub-rendered diagrams are also collected here: docs/diagrams.md

Architecture overview

  • The browser loads the Next.js web application from Vercel.
  • Organizer and guest interactions are handled through the web UI.
  • The application uses Supabase Auth for organizer sign-in.
  • Event, guest, agenda, and speaker data are stored in Supabase Postgres.
  • Row Level Security protects organizer-owned data.
  • Google Maps API and Places SDK are used for venue search, map display, and directions.
  • Production and staging share the same overall architecture but use separate deployment environments.

Mermaid: System Architecture

flowchart LR
    Guest["Guest User"] --> Browser["Web Browser"]
    Organizer["Organizer"] --> Browser

    Browser --> Vercel["Vercel / Next.js Web App"]
    Vercel --> Auth["Supabase Auth"]
    Vercel --> DB["Supabase Postgres"]
    Vercel --> Storage["Supabase Storage"]
    Vercel --> Maps["Google Maps API and Places SDK"]

    Auth --> DB
    DB --> RLS["Row Level Security Policies"]

    subgraph Environments
      Prod["Production: www.rizi.app"]
      Stage["Staging: staging.rizi.app"]
    end

    Prod -. deploy .-> Vercel
    Stage -. validate .-> Vercel

6. Components and Classes

The class and component relationships are documented in the GitHub repository: class-diagram.mmd

Frontend modules

  • Auth UI
    • Handles organizer sign up and sign in.
  • Event Management UI
    • Handles event creation, editing, publishing, and guest list access.
  • Public Event Page
    • Displays event details, agenda, speakers, and venue information at https://www.rizi.app/e/[slug].
  • Guest Registration UI
    • Collects guest details and submits registration requests.
  • Guest List UI
    • Shows registered guests and their attendance status.
  • Offline Check-in UI
    • Allows an organizer to mark guests as checked in on-site.

Backend service classes

  • AuthService
    • Responsibilities: organizer registration, login, session validation.
    • Key methods: registerOrganizer(), loginOrganizer(), getCurrentOrganizer().
  • EventService
    • Responsibilities: create, update, publish, and fetch events.
    • Key methods: createEvent(), updateEvent(), publishEvent(), getPublicEventBySlug().
  • GuestService
    • Responsibilities: register guests and list guests per event.
    • Key methods: registerGuest(), listGuestsByEvent(), getGuestById().
  • VenueLocationService
    • Responsibilities: process venue selection data from Google Maps.
    • Key methods: saveVenueLocation(), buildDirectionsUrl().
  • CheckInService
    • Responsibilities: mark guests as checked in and prevent duplicate check-in actions.
    • Key methods: checkInGuest(), getAttendanceStatus().

Mermaid: Class and Component Diagram

classDiagram
    class AuthUI {
        +renderLoginForm()
        +renderRegisterForm()
        +submitCredentials()
    }

    class EventManagementUI {
        +renderEventForm()
        +saveDraft()
        +publishEvent()
        +viewGuestList()
    }

    class PublicEventPage {
        +loadEventBySlug()
        +renderEventDetails()
        +showVenueDirections()
    }

    class GuestRegistrationUI {
        +renderRegistrationForm()
        +submitRegistration()
        +showConfirmation()
    }

    class GuestListUI {
        +renderGuestList()
        +filterGuests()
        +openCheckInScreen()
    }

    class OfflineCheckInUI {
        +searchGuest()
        +confirmCheckIn()
        +showAttendanceStatus()
    }

    class AuthService {
        +registerOrganizer()
        +loginOrganizer()
        +getCurrentOrganizer()
    }

    class EventService {
        +createEvent()
        +updateEvent()
        +publishEvent()
        +getPublicEventBySlug()
    }

    class GuestService {
        +registerGuest()
        +listGuestsByEvent()
        +getGuestById()
    }

    class VenueLocationService {
        +saveVenueLocation()
        +buildDirectionsUrl()
        +mapPlaceToVenueFields()
    }

    class CheckInService {
        +checkInGuest()
        +getAttendanceStatus()
        +preventDuplicateCheckIn()
    }

    class User {
        +uuid id
        +string email
        +string name
        +string role
    }

    class Event {
        +uuid id
        +uuid organizerId
        +string slug
        +string title
        +string status
        +int capacity
        +string placeId
        +float latitude
        +float longitude
    }

    class Guest {
        +uuid id
        +uuid eventId
        +string fullName
        +string email
        +string phone
        +string tier
        +string status
        +datetime checkedInAt
    }

    class AgendaItem {
        +uuid id
        +uuid eventId
        +uuid speakerId
        +string title
        +datetime startTime
        +datetime endTime
    }

    class Speaker {
        +uuid id
        +uuid eventId
        +string fullName
        +string jobTitle
        +string bio
    }

    AuthUI --> AuthService : uses
    EventManagementUI --> EventService : uses
    EventManagementUI --> GuestService : reads guests
    PublicEventPage --> EventService : loads event
    PublicEventPage --> VenueLocationService : gets map data
    GuestRegistrationUI --> GuestService : registers guest
    GuestListUI --> GuestService : lists guests
    OfflineCheckInUI --> CheckInService : checks in guest
    CheckInService --> GuestService : reads guest

    User "1" --> "many" Event : creates
    Event "1" --> "many" Guest : contains
    Event "1" --> "many" AgendaItem : schedules
    Event "1" --> "many" Speaker : features
    Speaker "0..1" --> "many" AgendaItem : presents

7. Database Design

The ER diagram is documented in the GitHub repository: database-er.mmd

Core tables

  • users
    • Stores organizer profile data linked to authentication records.
  • events
    • Stores event metadata, slug, capacity, branding, and venue details.
  • guests
    • Stores guest registration data and check-in status.
  • agenda_items
    • Stores schedule entries for an event.
  • speakers
    • Stores speaker details associated with an event.

Reduced schema decisions

  • Public event routing is slug-based under https://www.rizi.app/e/[slug].
  • Payment-related tables are excluded from the MVP design.
  • Subscription or premium-plan tables are excluded from the MVP design.
  • Venue location data may include place_id, address, latitude, and longitude.
  • The platform uses a single free MVP tier and excludes paid-plan enforcement.

Mermaid: Database ER Diagram

erDiagram
    USERS ||--o{ EVENTS : creates
    EVENTS ||--o{ GUESTS : registers
    EVENTS ||--o{ AGENDA_ITEMS : includes
    EVENTS ||--o{ SPEAKERS : features
    SPEAKERS o|--o{ AGENDA_ITEMS : may_present

    USERS {
        uuid id PK
        string email
        string name
        string role
        datetime created_at
    }

    EVENTS {
        uuid id PK
        uuid organizer_id FK
        string slug
        string title
        string status
        datetime start_date
        datetime end_date
        string venue_name
        string venue_address
        string city
        string place_id
        float latitude
        float longitude
        int capacity
        json brand_config
        datetime created_at
    }

    GUESTS {
        uuid id PK
        uuid event_id FK
        string full_name
        string email
        string phone
        string tier
        string status
        datetime checked_in_at
        datetime created_at
    }

    AGENDA_ITEMS {
        uuid id PK
        uuid event_id FK
        uuid speaker_id FK
        string title
        string item_type
        datetime start_time
        datetime end_time
        string location_name
    }

    SPEAKERS {
        uuid id PK
        uuid event_id FK
        string full_name
        string job_title
        string bio
    }

8. Sequence Diagrams

The key interaction diagrams are stored in the GitHub repository:

Covered scenarios

  • Organizer registration and sign in.
  • Organizer creates and publishes an event.
  • Guest opens the event page and registers.
  • Organizer performs offline/manual check-in.

Sequence coverage note

Together, the sequence diagrams cover the full MVP flow from organizer authentication to event publishing, guest registration, guest list retrieval, and offline check-in. The create/publish and guest-registration sequences also cover the Should Have stories around agenda, speakers, and venue directions at the level expected for this MVP.

Mermaid: Organizer Authentication

sequenceDiagram
    actor Organizer
    participant UI as Auth UI
    participant API as AuthService
    participant Auth as Supabase Auth
    participant DB as Supabase Postgres

    Organizer->>UI: Open sign up or sign in screen
    alt New organizer registration
        Organizer->>UI: Submit register form
        UI->>API: POST /api/auth/register
        API->>Auth: Create auth account
        Auth->>DB: Create organizer profile record
        DB-->>Auth: Profile saved
        Auth-->>API: Account created
        API-->>UI: Registration success
    else Existing organizer login
        Organizer->>UI: Submit login form
        UI->>API: POST /api/auth/login
        API->>Auth: Validate credentials
        Auth-->>API: Session returned
        API-->>UI: Authenticated session
    end

Mermaid: Create and Publish Event

sequenceDiagram
    actor Organizer
    participant UI as Event Management UI
    participant API as EventService
    participant Maps as VenueLocationService
    participant DB as Supabase Postgres

    Organizer->>UI: Open create event form
    Organizer->>UI: Enter title, dates, capacity, branding
    Organizer->>UI: Search venue
    UI->>Maps: Resolve place data from Google Maps
    Maps-->>UI: place_id, address, latitude, longitude
    Organizer->>UI: Save draft
    UI->>API: POST /api/events
    API->>DB: Insert draft event with slug and venue data
    DB-->>API: Event created
    API-->>UI: Draft event response
    Organizer->>UI: Add optional agenda and speakers
    UI->>API: PATCH /api/events/{eventId}
    API->>DB: Update event content
    DB-->>API: Event updated
    API-->>UI: Updated event response
    Organizer->>UI: Publish event
    UI->>API: POST /api/events/{eventId}/publish
    API->>DB: Update event status to published
    DB-->>API: Published event
    API-->>UI: Public URL returned

Mermaid: Guest Registration

sequenceDiagram
    actor Guest
    participant UI as Public Event Page
    participant API as GuestService
    participant Maps as VenueLocationService
    participant DB as Supabase Postgres

    Guest->>UI: Open /e/{slug}
    UI->>API: GET /api/public/events/{slug}
    API->>DB: Read published event by slug
    DB-->>API: Event details, agenda, speakers, venue
    API-->>UI: Event page payload
    UI->>Maps: Build directions link from venue data
    Maps-->>UI: Directions URL
    Guest->>UI: Review details and submit registration form
    UI->>API: POST /api/guests/register
    API->>DB: Validate event and create guest
    DB-->>API: Guest record created
    API-->>UI: Registration success response
    UI-->>Guest: Confirmation shown

Mermaid: Offline Check-in

sequenceDiagram
    actor Organizer
    participant UI as Guest List and Check-in UI
    participant GuestAPI as GuestService
    participant API as CheckInService
    participant DB as Supabase Postgres

    Organizer->>UI: Open guest list
    UI->>GuestAPI: GET /api/events/{eventId}/guests
    GuestAPI->>DB: Fetch registered guests
    DB-->>GuestAPI: Guest list
    GuestAPI-->>UI: Guest list response
    Organizer->>UI: Search guest and confirm check-in
    UI->>API: POST /api/guests/{guestId}/checkin
    API->>DB: Update guest status and checked_in_at
    DB-->>API: Updated guest
    API-->>UI: Check-in success response
    UI-->>Organizer: Attendance updated

9. API Specifications

The detailed endpoint definitions are documented in docs/api-spec.md.

MVP endpoint set

  • POST /api/auth/register
  • POST /api/auth/login
  • POST /api/events
  • GET /api/events
  • GET /api/events/{eventId}
  • PATCH /api/events/{eventId}
  • POST /api/events/{eventId}/publish
  • GET /api/public/events/{slug}
  • POST /api/guests/register
  • GET /api/events/{eventId}/guests
  • POST /api/guests/{guestId}/checkin

10. SCM and QA

The full plan is documented in docs/scm-qa-plan.md.

SCM summary

  • main is the protected branch.
  • Each task is developed in a short-lived feature branch.
  • Pull requests are reviewed before merge.
  • Commits stay small and tied to one task or fix.

QA summary

  • Manual smoke tests cover the main organizer and guest flows.
  • Targeted component and API tests are added where feasible.
  • Staging is used for validation before production release.

11. Technical Justifications

The full rationale is documented in docs/technical-justifications.md.

Main decisions

  • Supabase reduces backend setup overhead and provides Auth, Postgres, and access control quickly.
  • Vercel is a practical fit for Next.js deployment, preview environments, and fast iteration.
  • Google Maps is the most useful external integration for accurate venue location and directions.
  • Online payments are intentionally deferred to keep the MVP realistic and deliverable for a small student team.

12. Acceptance Criteria

  • The repository documents only the reduced MVP scope.
  • The diagrams match the documented architecture and database design.
  • The API specification aligns with the user stories and sequence diagrams.
  • The SCM and QA plan is realistic for a four-member student team.
  • The .docx submission file is generated from the repo content and ready to upload.

Section

API Specifications

API Specification

Canonical URLs

  • Canonical production URL: https://www.rizi.app
  • Production apex redirect: https://rizi.app
  • Staging URL: https://staging.rizi.app
  • Public event page format: https://www.rizi.app/e/{slug}

External Services

Supabase Platform Services

  • Purpose: organizer authentication, relational data storage, and access control.
  • Why chosen: rapid MVP setup with managed authentication, Postgres, and Row Level Security.
  • Project usage:
    • Organizer registration and login
    • Event, guest, agenda, and speaker storage
    • Access rules for organizer-owned data

Google Maps API and Places SDK

  • Purpose: venue search, address lookup, place selection, and directions support.
  • Why chosen: reliable place data, familiar map experience, and direct support for venue-based event workflows.
  • Project usage:
    • Organizer chooses a venue during event setup
    • The system stores place_id, address, latitude, and longitude
    • Guests receive map and directions support on the public event page

Internal API Standards

  • Content type: application/json
  • Authentication: organizer endpoints require a valid organizer session
  • Success formats: JSON objects or arrays
  • Error format example:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The event title is required."
  }
}

POST /api/auth/register

  • Purpose: create a new organizer account
  • Auth required: No
  • Input: JSON body

Example request

{
  "name": "Tariq Rashid",
  "email": "tariq@example.com",
  "password": "StrongPassword123!"
}

Example success response

Status: 201 Created

{
  "userId": "5b1a9b62-5c42-4e53-a93b-0cb81d0a28d1",
  "email": "tariq@example.com",
  "createdAt": "2026-04-25T14:40:00Z"
}

Status codes

  • 201 Created account created
  • 400 Bad Request invalid payload
  • 409 Conflict email already exists

POST /api/auth/login

  • Purpose: authenticate an organizer and start a session
  • Auth required: No
  • Input: JSON body

Example request

{
  "email": "tariq@example.com",
  "password": "StrongPassword123!"
}

Example success response

Status: 200 OK

{
  "accessToken": "session-or-jwt-token",
  "user": {
    "id": "5b1a9b62-5c42-4e53-a93b-0cb81d0a28d1",
    "name": "Tariq Rashid",
    "email": "tariq@example.com"
  }
}

Status codes

  • 200 OK authenticated
  • 400 Bad Request missing credentials
  • 401 Unauthorized invalid email or password

POST /api/events

  • Purpose: create a new event draft
  • Auth required: Organizer session
  • Input: JSON body

Example request

{
  "title": "Health Exhibition 2026",
  "description": "A focused health and innovation exhibition for students and startups.",
  "startDate": "2026-06-12T10:00:00Z",
  "endDate": "2026-06-12T18:00:00Z",
  "venue": {
    "name": "Riyadh Front Hall A",
    "address": "Riyadh Front, Riyadh, Saudi Arabia",
    "city": "Riyadh",
    "placeId": "ChIJExamplePlaceId123",
    "latitude": 24.7786,
    "longitude": 46.7386
  },
  "capacity": 500,
  "brandConfig": {
    "primaryColor": "#0F766E"
  }
}

Example success response

Status: 201 Created

{
  "eventId": "a9bc6b0d-e06d-49c9-944a-1fc0d9ec7e37",
  "slug": "health-exhibition-2026",
  "status": "draft"
}

Status codes

  • 201 Created event draft created
  • 400 Bad Request invalid payload
  • 401 Unauthorized organizer not authenticated

GET /api/events

  • Purpose: list the authenticated organizer's events
  • Auth required: Organizer session
  • Input: optional query parameters

Optional query parameters

  • status
  • page
  • pageSize

Example request

GET /api/events?status=published&page=1&pageSize=10

Example success response

Status: 200 OK

{
  "items": [
    {
      "id": "a9bc6b0d-e06d-49c9-944a-1fc0d9ec7e37",
      "title": "Health Exhibition 2026",
      "slug": "health-exhibition-2026",
      "status": "published"
    }
  ],
  "total": 1
}

Status codes

  • 200 OK events returned
  • 401 Unauthorized organizer not authenticated

GET /api/events/{eventId}

  • Purpose: fetch one organizer-owned event for management screens
  • Auth required: Organizer session
  • Input: path parameter

Example success response

Status: 200 OK

{
  "id": "a9bc6b0d-e06d-49c9-944a-1fc0d9ec7e37",
  "slug": "health-exhibition-2026",
  "title": "Health Exhibition 2026",
  "status": "draft",
  "venue": {
    "name": "Riyadh Front Hall A",
    "city": "Riyadh"
  },
  "capacity": 500,
  "guestCounts": {
    "registered": 0,
    "checkedIn": 0
  }
}

Status codes

  • 200 OK event found
  • 401 Unauthorized organizer not authenticated
  • 404 Not Found event not found or not owned by organizer

PATCH /api/events/{eventId}

  • Purpose: update an event draft or editable event fields
  • Auth required: Organizer session
  • Input: JSON body with any editable subset of fields

Example request

{
  "description": "Updated event description.",
  "agenda": [
    {
      "title": "Opening Session",
      "startTime": "2026-06-12T10:30:00Z",
      "endTime": "2026-06-12T11:00:00Z"
    }
  ],
  "speakers": [
    {
      "fullName": "Dr. Noura Al-Harbi",
      "jobTitle": "Healthcare Innovation Lead"
    }
  ]
}

Example success response

Status: 200 OK

{
  "id": "a9bc6b0d-e06d-49c9-944a-1fc0d9ec7e37",
  "updatedAt": "2026-04-25T15:20:00Z",
  "status": "draft"
}

Status codes

  • 200 OK event updated
  • 400 Bad Request invalid payload
  • 401 Unauthorized organizer not authenticated
  • 404 Not Found event not found

POST /api/events/{eventId}/publish

  • Purpose: publish an event and make the public page available
  • Auth required: Organizer session
  • Input: path parameter

Example success response

Status: 200 OK

{
  "id": "a9bc6b0d-e06d-49c9-944a-1fc0d9ec7e37",
  "slug": "health-exhibition-2026",
  "status": "published",
  "publicUrl": "https://www.rizi.app/e/health-exhibition-2026"
}

Status codes

  • 200 OK event published
  • 400 Bad Request event missing required publish fields
  • 401 Unauthorized organizer not authenticated
  • 404 Not Found event not found

GET /api/public/events/{slug}

  • Purpose: fetch the public event data shown on /e/{slug}
  • Auth required: No
  • Input: path parameter

Example success response

Status: 200 OK

{
  "slug": "health-exhibition-2026",
  "title": "Health Exhibition 2026",
  "description": "A focused health and innovation exhibition for students and startups.",
  "startDate": "2026-06-12T10:00:00Z",
  "endDate": "2026-06-12T18:00:00Z",
  "venue": {
    "name": "Riyadh Front Hall A",
    "address": "Riyadh Front, Riyadh, Saudi Arabia",
    "city": "Riyadh",
    "directionsUrl": "https://maps.google.com/..."
  },
  "agenda": [],
  "speakers": [],
  "registrationOpen": true
}

Status codes

  • 200 OK event returned
  • 404 Not Found slug not found or event not published

POST /api/guests/register

  • Purpose: register a guest for a published event
  • Auth required: No
  • Input: JSON body

Example request

{
  "eventId": "a9bc6b0d-e06d-49c9-944a-1fc0d9ec7e37",
  "fullName": "Sara Ahmed",
  "email": "sara@example.com",
  "phone": "+966500000000"
}

Example success response

Status: 201 Created

{
  "guestId": "c06828fc-bf5c-450f-bb4f-3e40cad1fc25",
  "status": "registered",
  "message": "Registration completed successfully."
}

Status codes

  • 201 Created guest registered
  • 400 Bad Request invalid payload
  • 404 Not Found event not found
  • 409 Conflict duplicate registration detected

GET /api/events/{eventId}/guests

  • Purpose: list registered guests for organizer operations
  • Auth required: Organizer session
  • Input: path parameter with optional filters

Optional query parameters

  • search
  • status
  • page
  • pageSize

Example request

GET /api/events/{eventId}/guests?search=sara&status=registered&page=1&pageSize=25

Example success response

Status: 200 OK

{
  "items": [
    {
      "guestId": "c06828fc-bf5c-450f-bb4f-3e40cad1fc25",
      "fullName": "Sara Ahmed",
      "email": "sara@example.com",
      "status": "registered",
      "checkedInAt": null
    }
  ],
  "total": 1,
  "counts": {
    "registered": 1,
    "checkedIn": 0
  }
}

Status codes

  • 200 OK guest list returned
  • 401 Unauthorized organizer not authenticated
  • 404 Not Found event not found

POST /api/guests/{guestId}/checkin

  • Purpose: mark a registered guest as checked in at the venue
  • Auth required: Organizer session
  • Input: path parameter

Example success response

Status: 200 OK

{
  "guestId": "c06828fc-bf5c-450f-bb4f-3e40cad1fc25",
  "status": "checked_in",
  "checkedInAt": "2026-06-12T09:58:00Z"
}

Status codes

  • 200 OK guest checked in
  • 401 Unauthorized organizer not authenticated
  • 404 Not Found guest not found
  • 409 Conflict guest already checked in

Out of Scope Endpoints

The reduced MVP intentionally excludes:

  • online payment endpoints
  • subscription or paid-plan endpoints
  • custom-domain management endpoints
  • advanced analytics endpoints

Section

SCM and QA Plan

SCM and QA Plan

Source Control Management

Branching model

  • main is the protected branch and represents the stable project state.
  • Every new task uses a short-lived feature branch named after the task, such as feature/event-publish-flow or docs/api-spec.
  • Hotfixes can use a dedicated hotfix/* branch if a production issue appears.

Pull request process

  • Open a pull request for every branch before merging to main.
  • At least one teammate reviews the pull request.
  • The author addresses comments before merge.
  • Pull requests should stay focused on one change set.

Commit strategy

  • Commit frequently with small, task-based commits.
  • Use clear messages such as Add guest registration API spec or Update reduced MVP architecture diagram.
  • Avoid mixing unrelated documentation and code changes in the same commit when possible.

Team workflow for a four-member student team

  • One person owns the current documentation baseline.
  • One person validates diagrams and architecture consistency.
  • One person checks API and database sections.
  • One person verifies language, formatting, and submission readiness.

Quality Assurance

Testing strategy

  • Prioritize manual smoke testing for the main MVP flows.
  • Add targeted unit or component tests where they provide clear value without slowing the team down.
  • Validate staging before any production-facing update.

Core smoke-test scenarios

  • Organizer can register and log in.
  • Organizer can create an event draft.
  • Organizer can publish the event and receive a valid slug route.
  • Guest can open the public event page.
  • Guest can submit the registration form successfully.
  • Organizer can view the guest list.
  • Organizer can mark a guest as checked in offline.

Test types

  • Unit tests
    • utility helpers
    • payload validation
    • service logic around event publishing and guest registration
  • Integration tests
    • API endpoint request and response behavior
    • database writes for event and guest flows
  • Manual UI tests
    • public event page
    • event creation form
    • guest registration form
    • guest list and check-in screen

Suggested tools

  • Framework/unit testing: Jest or Vitest
  • API testing: Postman or Bruno
  • Manual browser validation: Chrome or Edge
  • Deployment verification: Vercel preview or staging deployment

Deployment Validation

Environments

  • Production: https://www.rizi.app
  • Staging: https://staging.rizi.app

Release checks

  • Confirm the correct environment variables are configured.
  • Confirm the build succeeds on Vercel.
  • Confirm the main public route and at least one event slug route load successfully.
  • Confirm guest registration works in staging before promoting any release process to production.

Definition of Done for This Phase

  • Documentation files are complete and internally consistent.
  • Mermaid diagrams match the written architecture and API flows.
  • The submission .docx is generated and readable.
  • The repository reflects the reduced MVP scope and does not present out-of-scope platform features as current deliverables.

Section

Technical Justifications

Technical Justifications

Supabase

Supabase is justified for this MVP because it reduces backend setup time while still providing the core services required by the product. The team needs authentication, a relational database, and practical access control without spending the project budget and schedule on custom infrastructure.

Reasons

  • Built-in authentication for organizer accounts
  • Managed Postgres for structured event and guest data
  • Row Level Security to protect organizer-owned records
  • Fast setup for a small student team
  • Lower operational overhead than building and hosting a custom backend stack from scratch

Vercel

Vercel is justified because the documented frontend is based on Next.js and the team needs fast deployment, preview capability, and a simple path for staging and production environments.

Reasons

  • Strong fit for Next.js deployment
  • Fast iteration and redeployment
  • Suitable workflow for staging and production
  • Easy preview-style validation during development
  • Minimal platform overhead for a small team

Google Maps API and Places SDK

Google Maps is justified as the only core external integration in the MVP because event products depend on clear venue information. The team needs a reliable way to let organizers choose a location and help guests navigate to it.

Reasons

  • Accurate place search and structured venue data
  • Familiar guest experience for directions
  • Practical venue workflow for event creation
  • Supports address, place identifier, and coordinates for future enhancement

Offline Payment Decision

The project intentionally excludes online payment gateways from the MVP. This is a scope-control decision, not a product limitation statement for the long term.

Reasons

  • Payment integration would add security, compliance, and testing overhead
  • The current team size is small and time-constrained
  • The academic deliverable can be defended without commercial payment flows
  • Offline/manual payment handling is enough for the MVP phase

Reduced Scope Decision

The original product direction explored more advanced platform ideas, but the reduced MVP is the correct technical choice for this phase.

Reasons

  • The team consists of four members, most of them students
  • A smaller MVP is more likely to be completed, explained, and validated
  • A reduced architecture is easier to document clearly
  • Simpler scope improves demo readiness and lowers delivery risk

Path-Based Event URLs

The documentation standardizes on https://www.rizi.app/e/[slug] instead of custom domains or subdomains.

Reasons

  • Easier routing model for the MVP
  • Lower operational complexity
  • No dependency on custom DNS configuration
  • Easier to document, test, and present

Excluding AI From the Formal Submission Scope

The formal technical documentation does not present AI assistance as a core MVP system feature.

Reasons

  • The phase review is better supported by a conventional, defensible product baseline
  • AI-generated content is not necessary to explain the core event workflow
  • Removing AI from the main narrative keeps the architecture and API documentation cleaner

Section

All Diagrams

RiziEvents Diagrams

This page collects every Mermaid diagram used in the reduced MVP documentation so GitHub can render them in one place.

Story Coverage Matrix

User Story Diagram Coverage
Organizer creates an account and signs in Organizer Authentication Sequence, Class Diagram, System Architecture
Organizer creates an event with title, date, venue, and capacity Create and Publish Event Sequence, Class Diagram, ER Diagram
Organizer publishes an event to a public URL Create and Publish Event Sequence, System Architecture
Guest opens the public event page Guest Registration Sequence, System Architecture
Guest registers for the event Guest Registration Sequence, Class Diagram, ER Diagram
Organizer sees the registered guest list Offline Check-in Sequence, Class Diagram
Organizer checks in guests manually Offline Check-in Sequence, Class Diagram
Organizer adds agenda items ER Diagram, Class Diagram
Organizer adds speakers ER Diagram, Class Diagram
Guest uses venue directions System Architecture, Class Diagram

System Architecture

flowchart LR
    Guest["Guest User"] --> Browser["Web Browser"]
    Organizer["Organizer"] --> Browser

    Browser --> Vercel["Vercel / Next.js Web App"]
    Vercel --> Auth["Supabase Auth"]
    Vercel --> DB["Supabase Postgres"]
    Vercel --> Storage["Supabase Storage"]
    Vercel --> Maps["Google Maps API and Places SDK"]

    Auth --> DB
    DB --> RLS["Row Level Security Policies"]

    subgraph Environments
      Prod["Production: www.rizi.app"]
      Stage["Staging: staging.rizi.app"]
    end

    Prod -. deploy .-> Vercel
    Stage -. validate .-> Vercel

Class and Component Diagram

classDiagram
    class AuthUI {
        +renderLoginForm()
        +renderRegisterForm()
        +submitCredentials()
    }

    class EventManagementUI {
        +renderEventForm()
        +saveDraft()
        +publishEvent()
        +viewGuestList()
    }

    class PublicEventPage {
        +loadEventBySlug()
        +renderEventDetails()
        +showVenueDirections()
    }

    class GuestRegistrationUI {
        +renderRegistrationForm()
        +submitRegistration()
        +showConfirmation()
    }

    class GuestListUI {
        +renderGuestList()
        +filterGuests()
        +openCheckInScreen()
    }

    class OfflineCheckInUI {
        +searchGuest()
        +confirmCheckIn()
        +showAttendanceStatus()
    }

    class AuthService {
        +registerOrganizer()
        +loginOrganizer()
        +getCurrentOrganizer()
    }

    class EventService {
        +createEvent()
        +updateEvent()
        +publishEvent()
        +getPublicEventBySlug()
    }

    class GuestService {
        +registerGuest()
        +listGuestsByEvent()
        +getGuestById()
    }

    class VenueLocationService {
        +saveVenueLocation()
        +buildDirectionsUrl()
        +mapPlaceToVenueFields()
    }

    class CheckInService {
        +checkInGuest()
        +getAttendanceStatus()
        +preventDuplicateCheckIn()
    }

    class User {
        +uuid id
        +string email
        +string name
        +string role
    }

    class Event {
        +uuid id
        +uuid organizerId
        +string slug
        +string title
        +string status
        +int capacity
        +string placeId
        +float latitude
        +float longitude
    }

    class Guest {
        +uuid id
        +uuid eventId
        +string fullName
        +string email
        +string phone
        +string tier
        +string status
        +datetime checkedInAt
    }

    class AgendaItem {
        +uuid id
        +uuid eventId
        +uuid speakerId
        +string title
        +datetime startTime
        +datetime endTime
    }

    class Speaker {
        +uuid id
        +uuid eventId
        +string fullName
        +string jobTitle
        +string bio
    }

    AuthUI --> AuthService : uses
    EventManagementUI --> EventService : uses
    EventManagementUI --> GuestService : reads guests
    PublicEventPage --> EventService : loads event
    PublicEventPage --> VenueLocationService : gets map data
    GuestRegistrationUI --> GuestService : registers guest
    GuestListUI --> GuestService : lists guests
    OfflineCheckInUI --> CheckInService : checks in guest
    CheckInService --> GuestService : reads guest

    User "1" --> "many" Event : creates
    Event "1" --> "many" Guest : contains
    Event "1" --> "many" AgendaItem : schedules
    Event "1" --> "many" Speaker : features
    Speaker "0..1" --> "many" AgendaItem : presents

Database ER Diagram

erDiagram
    USERS ||--o{ EVENTS : creates
    EVENTS ||--o{ GUESTS : registers
    EVENTS ||--o{ AGENDA_ITEMS : includes
    EVENTS ||--o{ SPEAKERS : features
    SPEAKERS o|--o{ AGENDA_ITEMS : may_present

    USERS {
        uuid id PK
        string email
        string name
        string role
        datetime created_at
    }

    EVENTS {
        uuid id PK
        uuid organizer_id FK
        string slug
        string title
        string status
        datetime start_date
        datetime end_date
        string venue_name
        string venue_address
        string city
        string place_id
        float latitude
        float longitude
        int capacity
        json brand_config
        datetime created_at
    }

    GUESTS {
        uuid id PK
        uuid event_id FK
        string full_name
        string email
        string phone
        string tier
        string status
        datetime checked_in_at
        datetime created_at
    }

    AGENDA_ITEMS {
        uuid id PK
        uuid event_id FK
        uuid speaker_id FK
        string title
        string item_type
        datetime start_time
        datetime end_time
        string location_name
    }

    SPEAKERS {
        uuid id PK
        uuid event_id FK
        string full_name
        string job_title
        string bio
    }

Sequence: Organizer Authentication

sequenceDiagram
    actor Organizer
    participant UI as Auth UI
    participant API as AuthService
    participant Auth as Supabase Auth
    participant DB as Supabase Postgres

    Organizer->>UI: Open sign up or sign in screen
    alt New organizer registration
        Organizer->>UI: Submit register form
        UI->>API: POST /api/auth/register
        API->>Auth: Create auth account
        Auth->>DB: Create organizer profile record
        DB-->>Auth: Profile saved
        Auth-->>API: Account created
        API-->>UI: Registration success
    else Existing organizer login
        Organizer->>UI: Submit login form
        UI->>API: POST /api/auth/login
        API->>Auth: Validate credentials
        Auth-->>API: Session returned
        API-->>UI: Authenticated session
    end

Sequence: Create and Publish Event

sequenceDiagram
    actor Organizer
    participant UI as Event Management UI
    participant API as EventService
    participant Maps as VenueLocationService
    participant DB as Supabase Postgres

    Organizer->>UI: Open create event form
    Organizer->>UI: Enter title, dates, capacity, branding
    Organizer->>UI: Search venue
    UI->>Maps: Resolve place data from Google Maps
    Maps-->>UI: place_id, address, latitude, longitude
    Organizer->>UI: Save draft
    UI->>API: POST /api/events
    API->>DB: Insert draft event with slug and venue data
    DB-->>API: Event created
    API-->>UI: Draft event response
    Organizer->>UI: Add optional agenda and speakers
    UI->>API: PATCH /api/events/{eventId}
    API->>DB: Update event content
    DB-->>API: Event updated
    API-->>UI: Updated event response
    Organizer->>UI: Publish event
    UI->>API: POST /api/events/{eventId}/publish
    API->>DB: Update event status to published
    DB-->>API: Published event
    API-->>UI: Public URL returned

Sequence: Guest Registration

sequenceDiagram
    actor Guest
    participant UI as Public Event Page
    participant API as GuestService
    participant Maps as VenueLocationService
    participant DB as Supabase Postgres

    Guest->>UI: Open /e/{slug}
    UI->>API: GET /api/public/events/{slug}
    API->>DB: Read published event by slug
    DB-->>API: Event details, agenda, speakers, venue
    API-->>UI: Event page payload
    UI->>Maps: Build directions link from venue data
    Maps-->>UI: Directions URL
    Guest->>UI: Review details and submit registration form
    UI->>API: POST /api/guests/register
    API->>DB: Validate event and create guest
    DB-->>API: Guest record created
    API-->>UI: Registration success response
    UI-->>Guest: Confirmation shown

Sequence: Offline Check-in

sequenceDiagram
    actor Organizer
    participant UI as Guest List and Check-in UI
    participant GuestAPI as GuestService
    participant CheckIn as CheckInService
    participant DB as Supabase Postgres

    Organizer->>UI: Open guest list
    UI->>GuestAPI: GET /api/events/{eventId}/guests
    GuestAPI->>DB: Fetch registered guests
    DB-->>GuestAPI: Guest list
    GuestAPI-->>UI: Guest list response
    Organizer->>UI: Search guest and confirm check-in
    UI->>CheckIn: POST /api/guests/{guestId}/checkin
    CheckIn->>DB: Update guest status and checked_in_at
    DB-->>CheckIn: Updated guest
    CheckIn-->>UI: Check-in success response
    UI-->>Organizer: Attendance updated