diff --git a/ONBOARDING.md b/ONBOARDING.md new file mode 100644 index 0000000..4ffdc38 --- /dev/null +++ b/ONBOARDING.md @@ -0,0 +1,672 @@ +# SCEvents Onboarding + +## 0. Start Here + +### What this project does + +This document is for SCE developers joining work on SCEvents. The goal is to give you a working mental model of the project — what it does, how it connects to Clark, where the important code lives — so you can explore the repo on your own and dive into specific areas as your tasks require. + +SCEvents is SCE's event planning backend. It stores events, handles registrations and waitlists, and exposes a REST API. [Clark](https://github.com/SCE-Development/Clark) is the frontend members interact with; all event UI in Clark talks to SCEvents over HTTP. SCEvents is the main events system — there is no separate legacy events backend to worry about. + +For deeper design history and decisions, see the [SCEvents Documentation](https://docs.google.com/document/d/1K1va_5XcoPiI-ZY19f7KfWbIexqOdnR_RKz9MlP3C2U) Google Doc. This onboarding guide does not replace that document; it focuses on getting you oriented in the codebase. + +### 5-minute quick start + +From the SCEvents repo root, start the stack: + +```bash +docker compose -f docker-compose.dev.yml up --build -d +``` + +Have Clark running (see [Clark Getting Started](https://github.com/SCE-Development/Clark/wiki/Getting-Started); `sce run c` is the quickest path). Point Clark at SCEvents in `Clark/src/config/config.json`: + +```json +{ + "SCEvents": { + "BASE_URL": "http://localhost:8002" + } +} +``` + +Confirm SCEvents is up: `http://localhost:8002/ping` should return JSON. Open Clark's Events page at `/events` and confirm events load without the "SCEvents might be down" error. + +### Prerequisites + +- **Docker** — SCEvents is developed with Docker only +- **Clark** — run locally on day one; testing across the full stack is much easier with both services up +- **Test accounts** — create **member**, **officer**, and **admin** accounts via the [Clark Getting Started wiki](https://github.com/SCE-Development/Clark/wiki/Getting-Started) +- **Go** — needed to run unit tests and builds locally (see Ship → CI) +- **golangci-lint** v2.11.4 — needed to run lint locally (see Ship → CI) + + + +### Important links + +| Resource | Location | +| -------- | -------- | +| Quick local setup | [README.md](README.md) | +| Design doc | [Google Doc](https://docs.google.com/document/d/1K1va_5XcoPiI-ZY19f7KfWbIexqOdnR_RKz9MlP3C2U) | +| Clark setup | [Clark Getting Started wiki](https://github.com/SCE-Development/Clark/wiki/Getting-Started) | +| Integration testing | [testing/README.md](testing/README.md) | +| Migration tool | [cmd/README.md](cmd/README.md) | + +Diagrams are embedded in the sections below (`system_map.png`, `scevents.png`, `api_map.png`, `registration_flow.png`). + +--- + + + +## 1. System Overview + +### Architecture + +SCEvents is a Go service built on [Gin](https://github.com/gin-gonic/gin). It runs alongside four supporting services in local development: + +| Service | Role | +| ------- | ---- | +| **Go server** | HTTP API, background workers | +| **MongoDB** | Source of truth for events, registrations, waitlist entries | +| **Redis** | Fast cache for seat counts on capacity-limited events | +| **Kafka** | Async queue for processing registration requests | + +![SCEvents system map](system_map.png) + +*Full system map: Clark, nginx, auth, SCEvents server, MongoDB, Redis, and Kafka.* + +![SCEvents high-level overview](scevents.png) + +*Simplified overview: Clark and the docker-compose backend stack.* + +The [Excalidraw diagrams](https://excalidraw.com/#json=blzinrcwsw_ZrNasTCHi5,2kjWQhJKEaD1ROrF5Nan3A) are also kept up to date. Editable sources live in `docs/` (`scevents-frame1-system-map.excalidraw`, `scevents-frame2-clark-api-map.excalidraw`, `scevents-frame3-registration-flow.excalidraw`). + +When the server starts (`cmd/server/main.go`), it connects to MongoDB and Redis, spins up a Kafka consumer for registrations, starts a background publisher that auto-publishes scheduled events, and optionally runs periodic schema migrations. The HTTP server listens on port `8002` by default. + +### External systems / Clark + +In production, Clark's nginx proxy is the only entry point users hit. Browser requests to `/api/scevents/...` are rewritten and forwarded to the SCEvents server. Clark's own API (`/api/...`) is handled separately. You can see this in Clark's `nginx.conf`: + +``` +location /api/scevents/ { + ... + rewrite ^/api/scevents/?(.*)$ /$1 break; + proxy_pass http://scevents-server:8002; +} +``` + +Locally, Clark and SCEvents run as separate processes. Clark's frontend config points directly at the SCEvents port instead of going through nginx. + +SCEvents does not call back into Clark for business logic. The one integration point is authentication: when a request includes a Bearer token, SCEvents verifies it by POSTing to Clark's `/api/Auth/verify` endpoint. Clark returns the user's `_id` and `accessLevel`, which SCEvents uses to enforce permissions. Registration form answers and event data are sent from Clark to SCEvents as JSON in request bodies — SCEvents stores and validates them on its own. + +The API client layer in Clark lives in `Clark/src/APIFunctions/SCEvents.js`. Every Events page imports from there rather than calling fetch directly. + +### System dependencies + + +| Dependency | Purpose | +| ---------- | ------------------------------------------------------------------- | +| MongoDB | Events, registrations, waitlist entries | +| Redis | Seat headcount for capacity-limited events (`event::headcount`) | +| Kafka | Async registration processing (`registrations` topic) | +| Clark API | Token verification only (`/api/Auth/verify`) | + + + + +### Environments + + +| Environment | Clark `SCEvents.BASE_URL` | Notes | +| ----------- | ------------------------- | ------------------------------------------------------------------------------- | +| Local | `http://localhost:8002` | Clark and SCEvents run as separate processes | +| Deployed | `/api/scevents` | Routed through Clark's nginx proxy (see `Clark/src/config/config.example.json`) | + + +Staging and production are largely the same from a developer's perspective. The norm is to develop and verify locally, then deploy once changes look good on your machine. + +--- + + + +## 2. Understand the Product + +### Domain concepts + +**Events** (`pkg/models/event.go`) have a lifecycle driven by `status`: + +- `draft` — not visible to the general public +- `published` — open for registration (unless closed) +- `closed` — registration is no longer accepted + +Events can be `public` or `private`. Private events require the viewer to meet `minimum_visible_role`. Events can have a scheduled `publish_date`; a background job in `cmd/server/publisher.go` auto-publishes them when the time arrives. + +`max_attendees` controls capacity. A value of `-1` means unlimited (no Redis tracking). Any positive value enables capacity-limited registration with Redis headcount. + +Events support custom `registration_form` questions (textbox, multiple choice, dropdown, checkbox). Answers are validated server-side before a registration is accepted. + +**Registrations** are tracked as a `RegistrationRequest` (`pkg/models/registration.go`) with status `pending`, `accepted`, or `rejected`. Each request gets a unique `request_id` that the frontend polls until processing completes. + +**Waitlist** — when an event has `waitlist_enabled` and is at capacity, users can join the waitlist via `POST /events/:id/waitlist`. Waitlist entries are stored in MongoDB (`pkg/db/waitlist.go`, `pkg/models/waitlist.go`). + +Waitlists currently only support joining and checking whether a user is waitlisted. There is no automatic promotion when a seat opens, no leave-waitlist endpoint, and no Kafka processing for waitlist entries. Any promotion or cleanup workflow would need to be designed and implemented separately. + +**Redis and seat counts** — Redis holds a headcount per capacity-limited event. This gives a fast way to check remaining seats without hitting MongoDB on every registration attempt. When an event is created or its capacity changes, the headcount is initialized in Redis. The Kafka consumer decrements it atomically when accepting a registration. Unlimited events (`max_attendees == -1`) never touch Redis for capacity. + +### Glossary + + +| Term | Meaning | +| ---------------------- | ------------------------------------------------------------- | +| `request_id` | Unique ID for a registration request; used for status polling | +| `headcount` | Redis-tracked remaining seats for capacity-limited events | +| `registration_form` | Custom questions attached to an event | +| `publish_date` | Scheduled time when a draft event auto-publishes | +| `minimum_visible_role` | Role required to see a private event | + + + + +### User roles + +SCEvents trusts Clark for identity. Every protected endpoint checks the `Authorization: Bearer ` header by calling `CLIENT_API_URL/api/Auth/verify`. The response includes `accessLevel`, which maps to SCE membership states (defined in `pkg/middleware/auth.go` and synced with Clark's `Enums.js`): + + +| accessLevel | State | Typical use in SCEvents | +| ----------- | ---------- | ------------------------------------ | +| 0 | Non-member | Can register for events | +| 1 | Member | Can register for events | +| 2 | Officer | Can create, edit, and delete events | +| 3 | Admin | Same as officer for event management | + + +Routes are grouped by minimum access level in `cmd/server/main.go`: + +- **Public reads** (`GET /events`, `GET /events/:id`) use optional auth — anonymous users can view public events, but authenticated users get personalized metadata. +- **Authenticated** (non-member and above): registration, waitlist, and viewing own registration state. Attendance summaries, registration lists, registration details, and attendee lists also require the caller to be an admin of that event. +- **Officer and above**: creating, updating, and deleting events. + +When testing locally, log into Clark with accounts at member, officer, and admin levels to confirm the permission boundaries behave as expected. + +### Event admins + +In addition to site roles, each event has an `admins` list (`pkg/models/event.go`). This is separate from Clark membership level. + +- The event creator is always added to `admins` on create. +- **Update and delete** require officer-level route access *and* `CanEdit`: if the event has admins listed, only those users may modify it; if `admins` is empty, only site **admin** role may modify it. +- **Viewing registrations** (`GET .../registrations`, attendees dashboard) requires being an event admin (`loadEventAndAuthorizeAdmin`). +- **Event admins cannot register** for events they administer (`RegisterForEvent` rejects listed admins). + +Clark also filters draft/private visibility client-side in `Events.js` (`canUserSeeEvent`) — event admins and officers can see drafts before the public can. + +### Registration lifecycle + +1. User submits registration form → `pending` record created in MongoDB +2. Kafka message published with `request_id`, `event_id`, `user_id` +3. Consumer processes message → `accepted` or `rejected` (with `decision_reason`) +4. Frontend polls `GET /events/registrations/:request_id` until status is no longer `pending` + +Defined rejection reasons: `capacity_full`, `duplicate_user`, `event_closed`, `event_not_found`, `internal_error`, `invalid_payload`, and `already_processed`. The latter two are currently defined in the model but are not emitted by the consumer's active processing path. + +If Kafka publish fails after the pending record is created, the handler marks the registration as rejected with `internal_error`. + +--- + + + +## 3. Understand the Code + +### Codebase map + +``` +SCEvents/ +├── cmd/ +│ ├── server/ # Main entry point, route setup, background workers +│ └── migrate/ # One-off MongoDB backfill tool for new default fields +├── pkg/ +│ ├── config/ # Environment variable loading +│ ├── handlers/ # HTTP handlers (start here for API changes) +│ ├── middleware/ # Auth (Clark token verification) +│ ├── models/ # Event, Registration, Waitlist structs and validation +│ ├── db/ # MongoDB and Redis store implementations +│ ├── registration/ # Kafka producer and consumer +│ └── migration/ # Auto-migration logic for schema defaults +├── docker/ # Dockerfiles +├── docker-compose.dev.yml +└── testing/ # Integration and load tests +``` + + + +### UI map + +![Clark UI to API map](api_map.png) + +*Clark routes, components, SCEvents.js functions, and API endpoints by permission level.* + +All SCEvents-related UI lives under `Clark/src/Pages/Events/`. The API layer is `Clark/src/APIFunctions/SCEvents.js`. + + +| Clark route | Component | What it does | +| ----------------------------- | ---------------------------- | ----------------------------------------------------- | +| `/events` | `Events.js` | Calendar view of events; fetches via `getAllSCEvents` | +| `/events/:id/register` | `EventsRegistration.js` | Registration form for a single event | +| `/events/create` | `CreateEventPage.js` | Officer/admin event creation | +| `/events/:id/edit` | `EditEventPage.js` | Officer/admin event editing and deletion | +| `/events/:id/admin/attendees` | `EventAttendeesDashboard.js` | View registrations and attendance summary | + + +The calendar UI is split across `Clark/src/Pages/Events/Calendar/` (`CalendarView.js`, `EventPopup.js`, etc.). `EventPopup.js` handles per-event actions like registering or joining the waitlist from the calendar. + +Shared form logic for registration questions lives in `useEventQuestions.js` and `CreateEventFormQuestionBlock.js`. Utility helpers (date formatting, error messages) are in `eventUtils.js`. + +Clark mirrors SCEvents JSON field names in component state (snake_case like `max_attendees`, `registration_form`). When you change a field on the backend, you will usually need to trace it through the matching Clark page and `SCEvents.js` API function. + +Visibility filtering for which events appear on the calendar is handled client-side in `Events.js` (`canUserSeeEvent`). Draft events are only visible to event admins and officers/admins. Public and private events follow `visibility` and `minimum_visible_role` rules defined on the event model. + +### API overview + +All routes are under the `/events` prefix. The handler implementations are in `pkg/handlers/event.go`. + +**Public (optional auth)** + +- `GET /events/` — list events (supports `startDate` and `endDate` query params) +- `GET /events/:id` — get a single event +- `GET /events/registrations/:request_id` — poll registration status by request ID + +**Authenticated (member+)** + +- `POST /events/:id/register` — submit a registration (returns `request_id` for polling) +- `POST /events/:id/waitlist` — join the waitlist when an event is full +- `GET /events/:id/registration/me` — current user's registration state for an event +- `GET /events/:id/attendance` — attendance summary +- `GET /events/:id/registrations` — paginated list of registrations (for admins) +- `GET /events/:id/registrations/:request_id` — single registration detail +- `GET /events/:id/attendees` — attendee list + +**Officer+** + +- `POST /events/` — create event +- `PATCH /events/:id` — update event +- `DELETE /events/:id` — delete event and related data + +The Clark API client in `SCEvents.js` wraps each of these endpoints. When debugging, compare the network tab in your browser against the handler in `event.go` to trace a request end to end. + +The route-level `member+` check is not the complete authorization rule for event data. Registration lists, individual registration details, attendance summaries, and attendee lists additionally call event-admin authorization. Event editing and deletion require officer-level access plus the event's `CanEdit` rule. + +### Registration API example + +Submit a registration with a Clark Bearer token: + +```bash +curl -X POST http://localhost:8002/events//register \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "registrant": { + "name": "Test Member", + "email": "test@example.com", + "user_id": "" + }, + "registration_form_answers": {} + }' +``` + +The accepted request returns HTTP `202` with a `request_id`: + +```json +{ + "message": "registration request received", + "event_id": "", + "request_id": "" +} +``` + +Poll until `status` is no longer `pending`. The current endpoint requires the registering user's ID as a query parameter: + +```bash +curl "http://localhost:8002/events/registrations/?user_id=" +``` + +An accepted response has `"status": "accepted"`. A rejected response has `"status": "rejected"` and a `decision_reason`, such as `capacity_full`, `duplicate_user`, or `event_closed`. + +### Database / schema + + +| Store | Collections / keys | Contents | +| ------- | ---------------------- | ---------------------------------------------------- | +| MongoDB | `events` | Event documents (`pkg/models/event.go`) | +| MongoDB | `registrations` | Registration requests (`pkg/models/registration.go`) | +| MongoDB | `waitlists` | Waitlist entries (`pkg/models/waitlist.go`) | +| Redis | `event::headcount` | Remaining seats for capacity-limited events | + + +If you add a new field to an event or registration model with a `default` struct tag, existing MongoDB documents won't have that field until a migration runs. The server can auto-migrate on an interval (`AUTO_MIGRATE_ENABLED`), or you can run `go run ./cmd/migrate events` manually — see `cmd/README.md`. + +### Important design decisions + +- **Async registration** — registrations are enqueued to Kafka and processed by a consumer, not handled synchronously in the HTTP handler +- **Clark auth only** — SCEvents verifies identity via Clark but does not call Clark for business logic +- **Redis for capacity** — seat counts are cached in Redis for fast, concurrency-safe capacity checks; unlimited events skip Redis entirely +- **Optional auth on reads** — public event endpoints allow anonymous access but enrich responses when a valid token is present + +--- + + + +## 4. Follow the Data + +### Registration flow + +![Registration flow](registration_flow.png) + +*Async registration: handler → MongoDB → Kafka → consumer → Redis → polling.* + +Registration is asynchronous. Understanding this flow is central to working on SCEvents. + +1. **User submits the form** in Clark (`EventsRegistration.js` calls `registerForEvent`). +2. **SCEvents handler** (`RegisterForEvent` in `pkg/handlers/event.go`) validates the payload, checks for duplicate registrations, verifies the event is open, does a quick capacity check against Redis, validates form answers, and creates a `pending` registration in MongoDB. +3. **Kafka message** is published (`pkg/registration/producer.go`) with the `request_id`, `event_id`, and `user_id`. +4. **Consumer processes the message** (`pkg/registration/consumer.go`): + - Loads the pending registration from MongoDB + - Verifies the event still exists and is not closed + - Checks for duplicate accepted registrations + - If the event has a capacity limit, atomically takes a seat in Redis (`TryTakeEventSeat`) + - Marks the registration as `accepted`, or `rejected` with a reason +5. **Frontend polls** registration status via `GET /events/registrations/:request_id` until the status moves out of `pending`. + + + +### Authentication flow + +1. Clark frontend sends request to SCEvents with `Authorization: Bearer ` +2. SCEvents middleware calls `POST CLIENT_API_URL/api/Auth/verify` with the same token +3. Clark returns `{ _id, accessLevel }` +4. SCEvents sets `userID`, `userRole`, and `accessLevel` on the request context +5. Route-level middleware enforces minimum `accessLevel` for protected endpoints + +Public read endpoints use `OptionalAuth` — invalid or missing tokens proceed anonymously rather than returning 401. + +### Clark integration flow + +1. Clark UI component calls a function in `Clark/src/APIFunctions/SCEvents.js` +2. Request goes to `SCEvents.BASE_URL` + endpoint path + - Local: `http://localhost:8002/events/...` + - Deployed: `/api/scevents/events/...` → nginx rewrites to SCEvents server +3. SCEvents handler processes request, reads/writes MongoDB and Redis as needed +4. JSON response returned to Clark UI + + + +### Other important workflows + +**Auto-publish** — `cmd/server/publisher.go` runs on a 30-second ticker and publishes draft events whose `publish_date` has passed. + +**Waitlist** — when an event is at capacity and `waitlist_enabled`, users call `POST /events/:id/waitlist`. Entries are written directly to MongoDB (no Kafka). + +Waitlist entries are not automatically promoted into registrations when capacity becomes available. There is currently no endpoint for leaving a waitlist; duplicate joins are rejected and a waitlist entry remains until the event is deleted or a future workflow removes it. + +**Schema migration** — if `AUTO_MIGRATE_ENABLED` is true, the server periodically backfills missing default fields on existing documents. Manual backfills use `go run ./cmd/migrate events` or `go run ./cmd/migrate registrations`. + +--- + + + +## 5. Develop + +### Local setup + +SCEvents is developed with Docker only. From the SCEvents repo root: + +```bash +docker compose -f docker-compose.dev.yml up --build -d +``` + +This starts MongoDB (host port `8100`), Redis (`8101`), Kafka (`9092`), and the Go server with hot reload via Air (`8002`). + +### Local ports + +| Service | Host port | Notes | +| ------- | --------- | ----- | +| SCEvents API | `8002` | `GET /ping`, Clark `BASE_URL` target | +| MongoDB | `8100` | `mongosh mongodb://localhost:8100` | +| Redis | `8101` | `redis-cli -p 8101` | +| Kafka | `9092` | used internally; rarely touched directly | +| Clark frontend | `3000` | Events UI (`/events`) | +| Clark API | `8080` | auth verify (`CLIENT_API_URL`) | + +You should also have Clark running on day one. Follow the [Clark Getting Started wiki](https://github.com/SCE-Development/Clark/wiki/Getting-Started) to clone, set up, and run Clark (`sce run c` is the quickest path). Create test accounts at different access levels using the wiki's account creation steps. + +The server uses [Air](https://github.com/air-verse/air) for hot reload in Docker. Edit a `.go` file and the server restarts automatically. + +### Configuration + +Environment variables are set in `docker-compose.dev.yml`. The important ones for Clark integration: + + +| Variable | Default | Purpose | +| ---------------------- | ---------------------------------- | ----------------------------------- | +| `CLIENT_URL` | `http://localhost:3000` | Clark frontend origin (CORS) | +| `CLIENT_API_URL` | `http://host.docker.internal:8080` | Clark backend for auth verification | +| `SERVER_PORT` | `8002` | SCEvents HTTP port | +| `MONGO_URI` | `mongodb://mongodb:27017` | MongoDB connection | +| `REDIS_ADDR` | `redis:6379` | Redis connection | +| `KAFKA_BROKER` | `kafka:29092` | Kafka broker | +| `AUTO_MIGRATE_ENABLED` | `true` | Periodic schema backfill | + + +Clark config (`Clark/src/config/config.json`): + +```json +{ + "SCEvents": { + "BASE_URL": "http://localhost:8002" + } +} +``` + + + +### Common developer tasks + +- Adding or changing an API endpoint → `pkg/handlers/event.go`, then register the route in `cmd/server/main.go` +- Changing event or registration data shape → `pkg/models/`, then `pkg/db/` store methods +- Changing capacity or seat logic → `pkg/db/redis.go` and `pkg/registration/consumer.go` +- Changing auth rules → `pkg/middleware/auth.go` and route groups in `main.go` +- Changing the Clark UI → `Clark/src/Pages/Events/` and `Clark/src/APIFunctions/SCEvents.js` +- Database backfills for new fields with defaults → `cmd/migrate/` (see `cmd/README.md`) + + + +### Testing + +SCEvents has three layers of tests: + +**Unit tests** live alongside the code they test (`*_test.go` files in `pkg/`). CI runs `go test ./...` on every PR to `main` (see `.github/workflows/go-ci.yml`). + +**Integration tests** spin up the full Docker stack including a mock Clark auth server (`testing/integration/mock_clark/`). The mock echoes the Bearer token as a user ID with admin access level. Run them with: + +```bash +make integration +make integration TEST=create # event creation flow +make integration TEST=register # registration flow +``` + +See [testing/README.md](testing/README.md) for full details, teardown commands, and load testing with k6. + +**Linting** runs via `.github/workflows/lint.yml` on PRs. + +When you make a change, run the relevant unit tests locally. If your change touches registration or event creation flows, run the matching integration test before opening a PR. + +--- + + + +## 6. Debug + +### Troubleshooting + +Check SCEvents logs first: + +```bash +docker compose -f docker-compose.dev.yml logs -f server +``` + +| Symptom | Likely cause | What to check | +| ------- | ------------ | ------------- | +| Clark: "SCEvents might be down" | SCEvents not running or wrong `BASE_URL` | `curl http://localhost:8002/ping`; `Clark/src/config/config.json` → `SCEvents.BASE_URL` | +| Create/edit: "Is the SCEvents API running?" | Same as above | Docker stack up; port `8002` reachable | +| `401` on protected routes | Token verify failing | Clark API on `:8080`; `CLIENT_API_URL` in `docker-compose.dev.yml` (use `host.docker.internal:8080` when Clark runs on host) | +| CORS errors in browser | Frontend origin mismatch | `CLIENT_URL` matches where Clark runs (default `http://localhost:3000`) | +| Registration stuck `pending` | Kafka consumer not processing | `docker compose ... logs server` for consumer errors; Kafka container healthy | +| `403` editing an event | Not an event admin | User in event `admins` list, or site admin if event has no admins | +| `403` creating an event | Not officer/admin | Log in with officer or admin test account | +| Wrong seat count / capacity | Redis headcount out of sync | Restart after capacity changes; inspect `redis-cli -p 8101` key `event::headcount` | + +### Local recovery checklist + +Use these checks before changing data: + +```bash +# Follow the API, Kafka consumer, publisher, and migration logs +docker compose -f docker-compose.dev.yml logs -f server + +# Inspect a capacity key +redis-cli -p 8101 GET event::headcount + +# Check MongoDB registration and waitlist records +mongosh mongodb://localhost:8100 +use scevents +db.registrations.find({event_id: ""}).sort({created_at: -1}).limit(10) +db.waitlists.find({event_id: ""}).sort({created_at: 1}) +``` + +If a registration stays `pending`, check the server logs for Kafka connection or consumer errors first. The consumer only commits a Kafka message after processing succeeds, so processing errors can be retried after the underlying problem is fixed. A pending record created before a Kafka publish failure is normally marked `rejected` with `internal_error` by the handler. + +Redis headcount is a derived value and there is currently no standalone reconciliation command. If a local headcount is missing or incorrect, inspect the event and registration data before changing it; re-saving the event capacity through the normal event update path re-synchronizes its Redis headcount. Do not manually delete the key unless you are prepared to restore it before testing registrations. + +For schema changes that add fields with `default` tags, run the relevant migration from the repo root after confirming `MONGO_URI` points to the intended database: + +```bash +MONGO_URI=mongodb://localhost:8100 go run ./cmd/migrate events +MONGO_URI=mongodb://localhost:8100 go run ./cmd/migrate registrations +``` + +### Common errors + +Registration decision reasons defined by the model: + + +| Reason | Cause | +| ----------------- | --------------------------------------------------------- | +| `capacity_full` | Event at max capacity when consumer processed the request | +| `duplicate_user` | User already has an accepted registration | +| `event_closed` | Event status is `closed` | +| `event_not_found` | Event was deleted before consumer processed | +| `internal_error` | Kafka publish failed or other server error | +| `invalid_payload` | Reserved for invalid registration data | +| `already_processed` | Reserved for a registration that is no longer pending | + + +Clark UI shows "SCEvents might be down" when `getAllSCEvents` fails — usually means SCEvents isn't running or `BASE_URL` is misconfigured. + +Create/edit pages show a network hint: "Is the SCEvents API running (e.g. Docker on port 8002)?" when the API is unreachable. + +--- + + + +## 7. Ship + +### Branching + +Branch names follow the pattern `/`, for example `ernest_ma/adding_onboarding_doc`. + +### PRs + +Open a PR against `main` when your changes are ready. + +### Two-repo workflow + +SCEvents and Clark are **separate repositories**. Most feature work touches both: + +| Change type | Repos | +| ----------- | ----- | +| New/changed API field or endpoint | SCEvents + Clark (`SCEvents.js` + Events pages) | +| UI-only (labels, layout) | Clark only | +| Backend-only (capacity, consumer, auth) | SCEvents only | + +Typical flow: + +1. Implement and test the API change in SCEvents locally. +2. Update Clark's `SCEvents.js` and the matching page under `Clark/src/Pages/Events/`. +3. Open a PR in each repo (same branch naming: `/`). +4. Verify end-to-end with both services running before merge. + +If the API ships before Clark, new fields are simply unused until the frontend PR merges. Breaking API changes should land with the matching Clark update. + +### CI + +CI must pass before merge. Three workflows run on PRs to `main` — reproduce them locally from the SCEvents repo root: + +**Go build and unit tests** (`.github/workflows/go-ci.yml`): + +```bash +go mod tidy +go mod vendor +git diff --exit-code -- go.mod go.sum +go build ./... +go test ./... +``` + +The `git diff` step fails if `go mod tidy` changed `go.mod` or `go.sum`; commit those files if so. + +**Lint** (`.github/workflows/lint.yml` — requires [golangci-lint](https://golangci-lint.run/) v2.11.4): + +```bash +golangci-lint run --timeout=5m +``` + +**Integration tests** (`.github/workflows/integration.yml` — requires Docker): + +```bash +make integration +make teardown-integration +``` + + + +### Deployment + +Develop and verify locally, then deploy once changes look good on your machine. In deployed environments, Clark's nginx proxies `/api/scevents` to the SCEvents server. + +--- + + + +## 8. Ownership & Resources + +### Reference links + +| Resource | Location | +| -------- | -------- | +| Onboarding guide | [ONBOARDING.md](ONBOARDING.md) | +| Quick local setup | [README.md](README.md) | +| System map | `system_map.png` | +| High-level overview | `scevents.png` | +| Clark UI → API map | `api_map.png` | +| Registration flow | `registration_flow.png` | +| Excalidraw sources | `docs/*.excalidraw` | +| Clark API client | `Clark/src/APIFunctions/SCEvents.js` | +| Clark Events pages | `Clark/src/Pages/Events/` | +| Integration testing | [testing/README.md](testing/README.md) | +| Migration tool | [cmd/README.md](cmd/README.md) | + + + + +### External documentation + + +| Resource | Location | +| ----------- | --------------------------------------------------------------------------------------------- | +| Design doc | [Google Doc](https://docs.google.com/document/d/1K1va_5XcoPiI-ZY19f7KfWbIexqOdnR_RKz9MlP3C2U) | +| Clark setup | [Clark Getting Started wiki](https://github.com/SCE-Development/Clark/wiki/Getting-Started) | diff --git a/README.md b/README.md index a02642b..e6edbfd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # SCEvents Welcome to SCE's event planner platform! +**New to the project?** Start with [ONBOARDING.md](ONBOARDING.md). + ## Local Setup (requires Docker) ### 1. Clone the repository diff --git a/api_map.png b/api_map.png new file mode 100644 index 0000000..0d9a4aa Binary files /dev/null and b/api_map.png differ diff --git a/docs/scevents-frame1-system-map.excalidraw b/docs/scevents-frame1-system-map.excalidraw new file mode 100644 index 0000000..490290d --- /dev/null +++ b/docs/scevents-frame1-system-map.excalidraw @@ -0,0 +1,1404 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1055604844, + "version": 1, + "versionNonce": 1468374434, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_323719467", + "type": "text", + "x": 300, + "y": 8, + "width": 520, + "height": 36, + "text": "SCEvents \u2014 Frame 1: System Map", + "fontSize": 28, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "SCEvents \u2014 Frame 1: System Map", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1846775396, + "version": 1, + "versionNonce": 1578236334, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_193064428", + "type": "rectangle", + "x": 325, + "y": 55, + "width": 450, + "height": 52, + "backgroundColor": "#e7f5ff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_645418795", + "type": "text" + }, + { + "id": "id_631941629", + "type": "arrow" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2104799308, + "version": 1, + "versionNonce": 716683341, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_645418795", + "type": "text", + "x": 335, + "y": 65, + "width": 430, + "height": 32, + "text": "USER BROWSER", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_193064428", + "originalText": "USER BROWSER", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 493218352, + "version": 1, + "versionNonce": 820802970, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_625154398", + "type": "rectangle", + "x": 150, + "y": 135, + "width": 800, + "height": 310, + "backgroundColor": "#a5d8ff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_870952197", + "type": "text" + }, + { + "id": "id_631941629", + "type": "arrow" + }, + { + "id": "id_249534544", + "type": "arrow" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 270678431, + "version": 1, + "versionNonce": 1256870202, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_870952197", + "type": "text", + "x": 160, + "y": 145, + "width": 120, + "height": 28, + "text": "CLARK", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_625154398", + "originalText": "CLARK", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 415569232, + "version": 1, + "versionNonce": 1049187220, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_531571370", + "type": "rectangle", + "x": 185, + "y": 180, + "width": 310, + "height": 210, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_210738049", + "type": "text" + }, + { + "id": "id_167405313", + "type": "arrow" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 33761819, + "version": 1, + "versionNonce": 1751772299, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_210738049", + "type": "text", + "x": 195, + "y": 190, + "width": 290, + "height": 190, + "text": "React UI\n/events/* pages\nSCEvents.js", + "fontSize": 15, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_531571370", + "originalText": "React UI\n/events/* pages\nSCEvents.js", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1464395536, + "version": 1, + "versionNonce": 622573424, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_567068982", + "type": "rectangle", + "x": 595, + "y": 180, + "width": 310, + "height": 210, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_114147898", + "type": "text" + }, + { + "id": "id_249534544", + "type": "arrow" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1634476940, + "version": 1, + "versionNonce": 1544279175, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_114147898", + "type": "text", + "x": 605, + "y": 190, + "width": 290, + "height": 190, + "text": "Clark API :8080\n/api/Auth/verify\n(identity only)", + "fontSize": 15, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_567068982", + "originalText": "Clark API :8080\n/api/Auth/verify\n(identity only)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1659627790, + "version": 1, + "versionNonce": 522687051, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_224424736", + "type": "rectangle", + "x": 360, + "y": 345, + "width": 380, + "height": 72, + "backgroundColor": "#fff3bf", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_761984883", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1535450601, + "version": 1, + "versionNonce": 880576495, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_761984883", + "type": "text", + "x": 370, + "y": 355, + "width": 360, + "height": 52, + "text": "nginx (prod): /api/scevents \u2192 scevents-server:8002", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_224424736", + "originalText": "nginx (prod): /api/scevents \u2192 scevents-server:8002", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 88392603, + "version": 1, + "versionNonce": 741701798, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_684684725", + "type": "rectangle", + "x": 110, + "y": 480, + "width": 880, + "height": 390, + "backgroundColor": "#f8f9fa", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_452777486", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1473341543, + "version": 1, + "versionNonce": 658624555, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_452777486", + "type": "text", + "x": 125, + "y": 490, + "width": 200, + "height": 24, + "text": "docker-compose", + "fontSize": 18, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_684684725", + "originalText": "docker-compose", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1063555296, + "version": 1, + "versionNonce": 1538622304, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_913456026", + "type": "rectangle", + "x": 275, + "y": 535, + "width": 550, + "height": 95, + "backgroundColor": "#74c0fc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_132500592", + "type": "text" + }, + { + "id": "id_167405313", + "type": "arrow" + }, + { + "id": "id_249534544", + "type": "arrow" + }, + { + "id": "id_884458067", + "type": "arrow" + }, + { + "id": "id_691673812", + "type": "arrow" + }, + { + "id": "id_323908910", + "type": "arrow" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1989820553, + "version": 1, + "versionNonce": 1067636114, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_132500592", + "type": "text", + "x": 285, + "y": 545, + "width": 530, + "height": 75, + "text": "SCEvents (Gin :8002)\nhandlers \u00b7 middleware \u00b7 background workers", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_913456026", + "originalText": "SCEvents (Gin :8002)\nhandlers \u00b7 middleware \u00b7 background workers", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 932553985, + "version": 1, + "versionNonce": 1544195875, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_376781967", + "type": "rectangle", + "x": 140, + "y": 690, + "width": 250, + "height": 155, + "backgroundColor": "#b2f2bb", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_998887275", + "type": "text" + }, + { + "id": "id_884458067", + "type": "arrow" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 347183049, + "version": 1, + "versionNonce": 24578858, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_998887275", + "type": "text", + "x": 150, + "y": 700, + "width": 230, + "height": 135, + "text": "MongoDB\n\u00b7 events\n\u00b7 registrations\n\u00b7 waitlist", + "fontSize": 15, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_376781967", + "originalText": "MongoDB\n\u00b7 events\n\u00b7 registrations\n\u00b7 waitlist", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1181124311, + "version": 1, + "versionNonce": 386833526, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_328636652", + "type": "rectangle", + "x": 430, + "y": 690, + "width": 210, + "height": 155, + "backgroundColor": "#ffc9c9", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_913973006", + "type": "text" + }, + { + "id": "id_691673812", + "type": "arrow" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1216960936, + "version": 1, + "versionNonce": 1962133740, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_913973006", + "type": "text", + "x": 440, + "y": 700, + "width": 190, + "height": 135, + "text": "Redis\n\u00b7 seat headcount\n(capacity-limited events)", + "fontSize": 15, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_328636652", + "originalText": "Redis\n\u00b7 seat headcount\n(capacity-limited events)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2114365585, + "version": 1, + "versionNonce": 14247159, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_210505525", + "type": "rectangle", + "x": 680, + "y": 690, + "width": 210, + "height": 155, + "backgroundColor": "#ffec99", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_570912904", + "type": "text" + }, + { + "id": "id_323908910", + "type": "arrow" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 440816181, + "version": 1, + "versionNonce": 1240892393, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_570912904", + "type": "text", + "x": 690, + "y": 700, + "width": 190, + "height": 135, + "text": "Kafka\n\u00b7 registration queue\n(async processing)", + "fontSize": 15, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_210505525", + "originalText": "Kafka\n\u00b7 registration queue\n(async processing)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 763223791, + "version": 1, + "versionNonce": 1977197982, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_545584961", + "type": "rectangle", + "x": 930, + "y": 535, + "width": 210, + "height": 110, + "backgroundColor": "#e9ecef", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_210817204", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 352000660, + "version": 1, + "versionNonce": 1872116172, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_210817204", + "type": "text", + "x": 940, + "y": 545, + "width": 190, + "height": 90, + "text": "Local dev:\nBASE_URL =\nhttp://localhost:8002", + "fontSize": 13, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_545584961", + "originalText": "Local dev:\nBASE_URL =\nhttp://localhost:8002", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 565857351, + "version": 1, + "versionNonce": 1069313952, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_878404688", + "type": "rectangle", + "x": 930, + "y": 180, + "width": 210, + "height": 95, + "backgroundColor": "#e9ecef", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_909290517", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 243038254, + "version": 1, + "versionNonce": 1932922019, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_909290517", + "type": "text", + "x": 940, + "y": 190, + "width": 190, + "height": 75, + "text": "Deployed:\nBASE_URL =\n/api/scevents", + "fontSize": 13, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_878404688", + "originalText": "Deployed:\nBASE_URL =\n/api/scevents", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 628381445, + "version": 1, + "versionNonce": 1390765885, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_631941629", + "type": "arrow", + "x": 550, + "y": 107, + "width": 0, + "height": 28, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 28 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": { + "elementId": "id_625154398", + "mode": "orbit", + "fixedPoint": [ + 0.5, + 0 + ] + }, + "boundElements": null + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 877256419, + "version": 1, + "versionNonce": 1365754083, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_167405313", + "type": "arrow", + "x": 340, + "y": 390, + "width": 200, + "height": 145, + "points": [ + [ + 0, + 0 + ], + [ + 200, + 145 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": { + "elementId": "id_531571370", + "mode": "orbit", + "fixedPoint": [ + 0.5, + 1 + ] + }, + "endBinding": { + "elementId": "id_913456026", + "mode": "orbit", + "fixedPoint": [ + 0.15, + 0 + ] + }, + "boundElements": [ + { + "id": "id_273794680", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 625781752, + "version": 1, + "versionNonce": 599555785, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_273794680", + "type": "text", + "x": 390, + "y": 430, + "width": 170, + "height": 40, + "text": "API calls\n(events, register, CRUD)", + "fontSize": 13, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_167405313", + "originalText": "API calls\n(events, register, CRUD)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "seed": 2103484321, + "version": 1, + "versionNonce": 1353343280, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_249534544", + "type": "arrow", + "x": 520, + "y": 630, + "width": 200, + "height": 250, + "points": [ + [ + 0, + 0 + ], + [ + 200, + -250 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": { + "elementId": "id_913456026", + "mode": "orbit", + "fixedPoint": [ + 0.85, + 0 + ] + }, + "endBinding": { + "elementId": "id_567068982", + "mode": "orbit", + "fixedPoint": [ + 0.5, + 1 + ] + }, + "boundElements": [ + { + "id": "id_734372029", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 884826726, + "version": 1, + "versionNonce": 469851755, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_734372029", + "type": "text", + "x": 600, + "y": 500, + "width": 150, + "height": 36, + "text": "verify token\n(dashed = auth only)", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_249534544", + "originalText": "verify token\n(dashed = auth only)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1633242935, + "version": 1, + "versionNonce": 1247714919, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_884458067", + "type": "arrow", + "x": 380, + "y": 630, + "width": 90, + "height": 60, + "points": [ + [ + 0, + 0 + ], + [ + -90, + 60 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": { + "elementId": "id_913456026", + "mode": "orbit", + "fixedPoint": [ + 0.2, + 1 + ] + }, + "endBinding": { + "elementId": "id_376781967", + "mode": "orbit", + "fixedPoint": [ + 0.5, + 0 + ] + }, + "boundElements": [ + { + "id": "id_260799069", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 842298664, + "version": 1, + "versionNonce": 831526073, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_260799069", + "type": "text", + "x": 250, + "y": 640, + "width": 90, + "height": 24, + "text": "persist", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_884458067", + "originalText": "persist", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 129703856, + "version": 1, + "versionNonce": 1626906810, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_691673812", + "type": "arrow", + "x": 550, + "y": 630, + "width": 0, + "height": 60, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 60 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": { + "elementId": "id_913456026", + "mode": "orbit", + "fixedPoint": [ + 0.5, + 1 + ] + }, + "endBinding": { + "elementId": "id_328636652", + "mode": "orbit", + "fixedPoint": [ + 0.5, + 0 + ] + }, + "boundElements": [ + { + "id": "id_452680393", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 129582871, + "version": 1, + "versionNonce": 894621269, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_452680393", + "type": "text", + "x": 560, + "y": 655, + "width": 80, + "height": 20, + "text": "headcount", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_691673812", + "originalText": "headcount", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1646939381, + "version": 1, + "versionNonce": 1040884727, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_323908910", + "type": "arrow", + "x": 720, + "y": 630, + "width": 90, + "height": 60, + "points": [ + [ + 0, + 0 + ], + [ + 90, + 60 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": { + "elementId": "id_913456026", + "mode": "orbit", + "fixedPoint": [ + 0.8, + 1 + ] + }, + "endBinding": { + "elementId": "id_210505525", + "mode": "orbit", + "fixedPoint": [ + 0.5, + 0 + ] + }, + "boundElements": [ + { + "id": "id_925253818", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1724177164, + "version": 1, + "versionNonce": 614458342, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_925253818", + "type": "text", + "x": 760, + "y": 640, + "width": 90, + "height": 24, + "text": "enqueue", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_323908910", + "originalText": "enqueue", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/docs/scevents-frame2-clark-api-map.excalidraw b/docs/scevents-frame2-clark-api-map.excalidraw new file mode 100644 index 0000000..c6ca67b --- /dev/null +++ b/docs/scevents-frame2-clark-api-map.excalidraw @@ -0,0 +1,2191 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1896036738, + "version": 1, + "versionNonce": 1809344368, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_457554842", + "type": "text", + "x": 40, + "y": 8, + "width": 700, + "height": 36, + "text": "SCEvents \u2014 Frame 2: Clark UI \u2192 API Map", + "fontSize": 26, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "SCEvents \u2014 Frame 2: Clark UI \u2192 API Map", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1857465311, + "version": 1, + "versionNonce": 1283565234, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_382724007", + "type": "rectangle", + "x": 40, + "y": 50, + "width": 160, + "height": 28, + "backgroundColor": "#d3f9d8", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_264557670", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 783022269, + "version": 1, + "versionNonce": 25172214, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_264557670", + "type": "text", + "x": 48, + "y": 54, + "width": 144, + "height": 20, + "text": "Public / optional auth", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_382724007", + "originalText": "Public / optional auth", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 856593781, + "version": 1, + "versionNonce": 1006323649, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_345716312", + "type": "rectangle", + "x": 220, + "y": 50, + "width": 160, + "height": 28, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_472296799", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 266710055, + "version": 1, + "versionNonce": 317803366, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_472296799", + "type": "text", + "x": 228, + "y": 54, + "width": 144, + "height": 20, + "text": "Member+", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_345716312", + "originalText": "Member+", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1174009520, + "version": 1, + "versionNonce": 1644993880, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_777130184", + "type": "rectangle", + "x": 360, + "y": 50, + "width": 160, + "height": 28, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_904616644", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 335546495, + "version": 1, + "versionNonce": 946337263, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_904616644", + "type": "text", + "x": 368, + "y": 54, + "width": 144, + "height": 20, + "text": "Officer+", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_777130184", + "originalText": "Officer+", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1230721029, + "version": 1, + "versionNonce": 799838618, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_618326920", + "type": "rectangle", + "x": 40, + "y": 95, + "width": 150, + "height": 32, + "backgroundColor": "#e9ecef", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_951477036", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 625583106, + "version": 1, + "versionNonce": 1530065970, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_951477036", + "type": "text", + "x": 46, + "y": 99, + "width": 138, + "height": 24, + "text": "Clark route", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_618326920", + "originalText": "Clark route", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 6447515, + "version": 1, + "versionNonce": 173033964, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_293987904", + "type": "rectangle", + "x": 200, + "y": 95, + "width": 220, + "height": 32, + "backgroundColor": "#e9ecef", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_409037758", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1113314931, + "version": 1, + "versionNonce": 299078392, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_409037758", + "type": "text", + "x": 206, + "y": 99, + "width": 208, + "height": 24, + "text": "Component", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_293987904", + "originalText": "Component", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2073358990, + "version": 1, + "versionNonce": 1872246237, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_510768296", + "type": "rectangle", + "x": 430, + "y": 95, + "width": 240, + "height": 32, + "backgroundColor": "#e9ecef", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_151996363", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2092635606, + "version": 1, + "versionNonce": 611141841, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_151996363", + "type": "text", + "x": 436, + "y": 99, + "width": 228, + "height": 24, + "text": "SCEvents.js", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_510768296", + "originalText": "SCEvents.js", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 289180839, + "version": 1, + "versionNonce": 1350300106, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_498938458", + "type": "rectangle", + "x": 680, + "y": 95, + "width": 320, + "height": 32, + "backgroundColor": "#e9ecef", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_428229847", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 436048691, + "version": 1, + "versionNonce": 726815158, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_428229847", + "type": "text", + "x": 686, + "y": 99, + "width": 308, + "height": 24, + "text": "API endpoint", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_498938458", + "originalText": "API endpoint", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 188262215, + "version": 1, + "versionNonce": 1909344871, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_367392818", + "type": "rectangle", + "x": 40, + "y": 131, + "width": 150, + "height": 72, + "backgroundColor": "#d3f9d8", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_191525299", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1009209983, + "version": 1, + "versionNonce": 516128043, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_191525299", + "type": "text", + "x": 46, + "y": 135, + "width": 138, + "height": 64, + "text": "/events", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_367392818", + "originalText": "/events", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1719608652, + "version": 1, + "versionNonce": 68274025, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_577105151", + "type": "rectangle", + "x": 200, + "y": 131, + "width": 220, + "height": 72, + "backgroundColor": "#d3f9d8", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_405360631", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 766647206, + "version": 1, + "versionNonce": 1545204882, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_405360631", + "type": "text", + "x": 206, + "y": 135, + "width": 208, + "height": 64, + "text": "Events.js\nCalendar/*", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_577105151", + "originalText": "Events.js\nCalendar/*", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2054126624, + "version": 1, + "versionNonce": 1798646590, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_680067299", + "type": "rectangle", + "x": 430, + "y": 131, + "width": 240, + "height": 72, + "backgroundColor": "#d3f9d8", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_601434746", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 51457618, + "version": 1, + "versionNonce": 1723788098, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_601434746", + "type": "text", + "x": 436, + "y": 135, + "width": 228, + "height": 64, + "text": "getAllSCEvents", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_680067299", + "originalText": "getAllSCEvents", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1565159392, + "version": 1, + "versionNonce": 792147493, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_839257217", + "type": "rectangle", + "x": 680, + "y": 131, + "width": 320, + "height": 72, + "backgroundColor": "#d3f9d8", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_649699911", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1896704779, + "version": 1, + "versionNonce": 507266849, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_649699911", + "type": "text", + "x": 686, + "y": 135, + "width": 308, + "height": 64, + "text": "GET /events/\n(?startDate & endDate)", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_839257217", + "originalText": "GET /events/\n(?startDate & endDate)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 843264234, + "version": 1, + "versionNonce": 1752354546, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_610007795", + "type": "rectangle", + "x": 40, + "y": 207, + "width": 150, + "height": 72, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_299717048", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 556241927, + "version": 1, + "versionNonce": 2043206307, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_299717048", + "type": "text", + "x": 46, + "y": 211, + "width": 138, + "height": 64, + "text": "EventPopup", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_610007795", + "originalText": "EventPopup", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 653603910, + "version": 1, + "versionNonce": 255840351, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_740178642", + "type": "rectangle", + "x": 200, + "y": 207, + "width": 220, + "height": 72, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_214056040", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 136087396, + "version": 1, + "versionNonce": 3697738, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_214056040", + "type": "text", + "x": 206, + "y": 211, + "width": 208, + "height": 64, + "text": "EventPopup.js", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_740178642", + "originalText": "EventPopup.js", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 849253802, + "version": 1, + "versionNonce": 1367022573, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_241892158", + "type": "rectangle", + "x": 430, + "y": 207, + "width": 240, + "height": 72, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_419380105", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 987294726, + "version": 1, + "versionNonce": 1438744276, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_419380105", + "type": "text", + "x": 436, + "y": 211, + "width": 228, + "height": 64, + "text": "getMyEventRegistrationState\ngetEventAttendanceSummary\njoinWaitlistForSCEvent", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_241892158", + "originalText": "getMyEventRegistrationState\ngetEventAttendanceSummary\njoinWaitlistForSCEvent", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 813676145, + "version": 1, + "versionNonce": 1901994553, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_265553700", + "type": "rectangle", + "x": 680, + "y": 207, + "width": 320, + "height": 72, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_503955398", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2077376600, + "version": 1, + "versionNonce": 725920461, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_503955398", + "type": "text", + "x": 686, + "y": 211, + "width": 308, + "height": 64, + "text": "GET .../registration/me\nGET .../attendance\nPOST .../waitlist", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_265553700", + "originalText": "GET .../registration/me\nGET .../attendance\nPOST .../waitlist", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 224264115, + "version": 1, + "versionNonce": 190806654, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_174554579", + "type": "rectangle", + "x": 40, + "y": 283, + "width": 150, + "height": 72, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_365142095", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 213233619, + "version": 1, + "versionNonce": 1195451670, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_365142095", + "type": "text", + "x": 46, + "y": 287, + "width": 138, + "height": 64, + "text": "/events/:id/register", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_174554579", + "originalText": "/events/:id/register", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 854005672, + "version": 1, + "versionNonce": 1656192110, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_177905810", + "type": "rectangle", + "x": 200, + "y": 283, + "width": 220, + "height": 72, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_920628831", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 349796080, + "version": 1, + "versionNonce": 723304431, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_920628831", + "type": "text", + "x": 206, + "y": 287, + "width": 208, + "height": 64, + "text": "EventsRegistration.js", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_177905810", + "originalText": "EventsRegistration.js", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1752138784, + "version": 1, + "versionNonce": 797729777, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_447428592", + "type": "rectangle", + "x": 430, + "y": 283, + "width": 240, + "height": 72, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_147413926", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 321131311, + "version": 1, + "versionNonce": 1363928247, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_147413926", + "type": "text", + "x": 436, + "y": 287, + "width": 228, + "height": 64, + "text": "getEventByID\nregisterForEvent", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_447428592", + "originalText": "getEventByID\nregisterForEvent", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1061601376, + "version": 1, + "versionNonce": 1903555980, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_711094224", + "type": "rectangle", + "x": 680, + "y": 283, + "width": 320, + "height": 72, + "backgroundColor": "#d0ebff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_199562047", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1740538565, + "version": 1, + "versionNonce": 749990044, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_199562047", + "type": "text", + "x": 686, + "y": 287, + "width": 308, + "height": 64, + "text": "GET /events/:id\nPOST /events/:id/register", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_711094224", + "originalText": "GET /events/:id\nPOST /events/:id/register", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1627622888, + "version": 1, + "versionNonce": 252666160, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_845155171", + "type": "rectangle", + "x": 40, + "y": 359, + "width": 150, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_302484063", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1736388296, + "version": 1, + "versionNonce": 1162889129, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_302484063", + "type": "text", + "x": 46, + "y": 363, + "width": 138, + "height": 64, + "text": "/events/create", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_845155171", + "originalText": "/events/create", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 890090316, + "version": 1, + "versionNonce": 1151034637, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_727437547", + "type": "rectangle", + "x": 200, + "y": 359, + "width": 220, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_730730031", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2094018510, + "version": 1, + "versionNonce": 281822691, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_730730031", + "type": "text", + "x": 206, + "y": 363, + "width": 208, + "height": 64, + "text": "CreateEventPage.js", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_727437547", + "originalText": "CreateEventPage.js", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1899541218, + "version": 1, + "versionNonce": 1903977830, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_374963440", + "type": "rectangle", + "x": 430, + "y": 359, + "width": 240, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_861369827", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 337910010, + "version": 1, + "versionNonce": 552306939, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_861369827", + "type": "text", + "x": 436, + "y": 363, + "width": 228, + "height": 64, + "text": "createSCEvent", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_374963440", + "originalText": "createSCEvent", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1201873120, + "version": 1, + "versionNonce": 425796708, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_188865179", + "type": "rectangle", + "x": 680, + "y": 359, + "width": 320, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_494938529", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1732009640, + "version": 1, + "versionNonce": 1045084098, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_494938529", + "type": "text", + "x": 686, + "y": 363, + "width": 308, + "height": 64, + "text": "POST /events/", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_188865179", + "originalText": "POST /events/", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 194048986, + "version": 1, + "versionNonce": 907455312, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_562484380", + "type": "rectangle", + "x": 40, + "y": 435, + "width": 150, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_928513149", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 600963244, + "version": 1, + "versionNonce": 315525480, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_928513149", + "type": "text", + "x": 46, + "y": 439, + "width": 138, + "height": 64, + "text": "/events/:id/edit", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_562484380", + "originalText": "/events/:id/edit", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1422613913, + "version": 1, + "versionNonce": 1652007798, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_412447074", + "type": "rectangle", + "x": 200, + "y": 435, + "width": 220, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_555465253", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 712892312, + "version": 1, + "versionNonce": 633569016, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_555465253", + "type": "text", + "x": 206, + "y": 439, + "width": 208, + "height": 64, + "text": "EditEventPage.js", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_412447074", + "originalText": "EditEventPage.js", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 967536643, + "version": 1, + "versionNonce": 1719567639, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_756256028", + "type": "rectangle", + "x": 430, + "y": 435, + "width": 240, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_747836089", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1822644946, + "version": 1, + "versionNonce": 17359118, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_747836089", + "type": "text", + "x": 436, + "y": 439, + "width": 228, + "height": 64, + "text": "getEventByID\nupdateSCEvent\ndeleteSCEvent", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_756256028", + "originalText": "getEventByID\nupdateSCEvent\ndeleteSCEvent", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 863304183, + "version": 1, + "versionNonce": 1071633686, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_993963085", + "type": "rectangle", + "x": 680, + "y": 435, + "width": 320, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_154834528", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1567426505, + "version": 1, + "versionNonce": 822174107, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_154834528", + "type": "text", + "x": 686, + "y": 439, + "width": 308, + "height": 64, + "text": "GET /events/:id\nPATCH /events/:id\nDELETE /events/:id", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_993963085", + "originalText": "GET /events/:id\nPATCH /events/:id\nDELETE /events/:id", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2133691310, + "version": 1, + "versionNonce": 702090887, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_900254999", + "type": "rectangle", + "x": 40, + "y": 511, + "width": 150, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_537169571", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 783099980, + "version": 1, + "versionNonce": 128269012, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_537169571", + "type": "text", + "x": 46, + "y": 515, + "width": 138, + "height": 64, + "text": "/events/:id/admin/attendees", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_900254999", + "originalText": "/events/:id/admin/attendees", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1229463989, + "version": 1, + "versionNonce": 1751624437, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_553374833", + "type": "rectangle", + "x": 200, + "y": 511, + "width": 220, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_462116500", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1425985297, + "version": 1, + "versionNonce": 1874026942, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_462116500", + "type": "text", + "x": 206, + "y": 515, + "width": 208, + "height": 64, + "text": "EventAttendeesDashboard.js", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_553374833", + "originalText": "EventAttendeesDashboard.js", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 164212423, + "version": 1, + "versionNonce": 2126511764, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_752611038", + "type": "rectangle", + "x": 430, + "y": 511, + "width": 240, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_342245636", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2080364417, + "version": 1, + "versionNonce": 1594049139, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_342245636", + "type": "text", + "x": 436, + "y": 515, + "width": 228, + "height": 64, + "text": "getEventRegistrations\ngetEventRegistrationByRequestId", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_752611038", + "originalText": "getEventRegistrations\ngetEventRegistrationByRequestId", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1234372682, + "version": 1, + "versionNonce": 1946216561, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_710487937", + "type": "rectangle", + "x": 680, + "y": 511, + "width": 320, + "height": 72, + "backgroundColor": "#ffe8cc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_865834094", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1551519709, + "version": 1, + "versionNonce": 1417920611, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_865834094", + "type": "text", + "x": 686, + "y": 515, + "width": 308, + "height": 64, + "text": "GET .../registrations\nGET .../registrations/:request_id", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_710487937", + "originalText": "GET .../registrations\nGET .../registrations/:request_id", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 14235566, + "version": 1, + "versionNonce": 14175158, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_942378941", + "type": "rectangle", + "x": 40, + "y": 599, + "width": 960, + "height": 56, + "backgroundColor": "#fff3bf", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_157459133", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1466859513, + "version": 1, + "versionNonce": 36571082, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_157459133", + "type": "text", + "x": 50, + "y": 605, + "width": 940, + "height": 44, + "text": "Clark also gates routes in Routes.js (officer/admin). SCEvents enforces the same levels in pkg/middleware/auth.go.\nAll calls go through Clark/src/APIFunctions/SCEvents.js using SCEvents.BASE_URL.", + "fontSize": 13, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_942378941", + "originalText": "Clark also gates routes in Routes.js (officer/admin). SCEvents enforces the same levels in pkg/middleware/auth.go.\nAll calls go through Clark/src/APIFunctions/SCEvents.js using SCEvents.BASE_URL.", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/docs/scevents-frame3-registration-flow.excalidraw b/docs/scevents-frame3-registration-flow.excalidraw new file mode 100644 index 0000000..cc16355 --- /dev/null +++ b/docs/scevents-frame3-registration-flow.excalidraw @@ -0,0 +1,1480 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1084234783, + "version": 1, + "versionNonce": 1852755360, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_278217820", + "type": "text", + "x": 40, + "y": 8, + "width": 800, + "height": 36, + "text": "SCEvents \u2014 Frame 3: Registration Flow", + "fontSize": 26, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "SCEvents \u2014 Frame 3: Registration Flow", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1178857914, + "version": 1, + "versionNonce": 1810399794, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_897005166", + "type": "rectangle", + "x": 40, + "y": 55, + "width": 155, + "height": 70, + "backgroundColor": "#a5d8ff", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_605245738", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2116002372, + "version": 1, + "versionNonce": 967519405, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_605245738", + "type": "text", + "x": 46, + "y": 63, + "width": 143, + "height": 54, + "text": "Clark UI\nEventsRegistration.js\nregisterForEvent()", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_897005166", + "originalText": "Clark UI\nEventsRegistration.js\nregisterForEvent()", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 476205537, + "version": 1, + "versionNonce": 1299117159, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_451519003", + "type": "rectangle", + "x": 220, + "y": 55, + "width": 155, + "height": 70, + "backgroundColor": "#74c0fc", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_484361274", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 244835465, + "version": 1, + "versionNonce": 1842175154, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_484361274", + "type": "text", + "x": 226, + "y": 63, + "width": 143, + "height": 54, + "text": "SCEvents\nRegisterForEvent\nhandler", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_451519003", + "originalText": "SCEvents\nRegisterForEvent\nhandler", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1960928756, + "version": 1, + "versionNonce": 338971585, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_666271727", + "type": "rectangle", + "x": 400, + "y": 55, + "width": 155, + "height": 70, + "backgroundColor": "#b2f2bb", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_105495178", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1960139958, + "version": 1, + "versionNonce": 1063542691, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_105495178", + "type": "text", + "x": 406, + "y": 63, + "width": 143, + "height": 54, + "text": "MongoDB\nregistrations\ncollection", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_666271727", + "originalText": "MongoDB\nregistrations\ncollection", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1470827262, + "version": 1, + "versionNonce": 1183220646, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_916273981", + "type": "rectangle", + "x": 580, + "y": 55, + "width": 155, + "height": 70, + "backgroundColor": "#ffec99", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_859408380", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1711815603, + "version": 1, + "versionNonce": 1639313815, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_859408380", + "type": "text", + "x": 586, + "y": 63, + "width": 143, + "height": 54, + "text": "Kafka\nregistrations\ntopic", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_916273981", + "originalText": "Kafka\nregistrations\ntopic", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1211636435, + "version": 1, + "versionNonce": 498489149, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_306687338", + "type": "rectangle", + "x": 760, + "y": 55, + "width": 155, + "height": 70, + "backgroundColor": "#ffd8a8", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_118652258", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 246372411, + "version": 1, + "versionNonce": 1895953887, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_118652258", + "type": "text", + "x": 766, + "y": 63, + "width": 143, + "height": 54, + "text": "Consumer\npkg/registration\nconsumer.go", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_306687338", + "originalText": "Consumer\npkg/registration\nconsumer.go", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 756194164, + "version": 1, + "versionNonce": 290449172, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_946004380", + "type": "rectangle", + "x": 940, + "y": 55, + "width": 155, + "height": 70, + "backgroundColor": "#ffc9c9", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_354182694", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 68152033, + "version": 1, + "versionNonce": 85719015, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_354182694", + "type": "text", + "x": 946, + "y": 63, + "width": 143, + "height": 54, + "text": "Redis\nseat headcount\n(if capped)", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_946004380", + "originalText": "Redis\nseat headcount\n(if capped)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#adb5bd", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "seed": 941940429, + "version": 1, + "versionNonce": 1687302693, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_330382667", + "type": "line", + "x": 117, + "y": 125, + "width": 0, + "height": 495, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 495 + ] + ] + }, + { + "angle": 0, + "strokeColor": "#adb5bd", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "seed": 1601429913, + "version": 1, + "versionNonce": 251614960, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_617902411", + "type": "line", + "x": 297, + "y": 125, + "width": 0, + "height": 495, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 495 + ] + ] + }, + { + "angle": 0, + "strokeColor": "#adb5bd", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "seed": 1131505551, + "version": 1, + "versionNonce": 43380972, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_523042974", + "type": "line", + "x": 477, + "y": 125, + "width": 0, + "height": 495, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 495 + ] + ] + }, + { + "angle": 0, + "strokeColor": "#adb5bd", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "seed": 1643372322, + "version": 1, + "versionNonce": 1316387336, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_294931032", + "type": "line", + "x": 657, + "y": 125, + "width": 0, + "height": 495, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 495 + ] + ] + }, + { + "angle": 0, + "strokeColor": "#adb5bd", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "seed": 1898758470, + "version": 1, + "versionNonce": 1742881136, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_620124404", + "type": "line", + "x": 837, + "y": 125, + "width": 0, + "height": 495, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 495 + ] + ] + }, + { + "angle": 0, + "strokeColor": "#adb5bd", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "seed": 2037283324, + "version": 1, + "versionNonce": 1204345300, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_891980516", + "type": "line", + "x": 1017, + "y": 125, + "width": 0, + "height": 495, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 495 + ] + ] + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1862446360, + "version": 1, + "versionNonce": 1525632864, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_697440068", + "type": "arrow", + "x": 117, + "y": 155, + "width": 180, + "height": 0, + "points": [ + [ + 0, + 0 + ], + [ + 180, + 0 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": null, + "boundElements": [ + { + "id": "id_489126341", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1030833666, + "version": 1, + "versionNonce": 1248182807, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_489126341", + "type": "text", + "x": 127, + "y": 133, + "width": 160, + "height": 40, + "text": "1. POST /events/:id/register\n(form + Bearer token)", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_697440068", + "originalText": "1. POST /events/:id/register\n(form + Bearer token)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1667593675, + "version": 1, + "versionNonce": 871105489, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_405724430", + "type": "arrow", + "x": 297, + "y": 215, + "width": 180, + "height": 0, + "points": [ + [ + 0, + 0 + ], + [ + 180, + 0 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": null, + "boundElements": [ + { + "id": "id_745745425", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1325418383, + "version": 1, + "versionNonce": 1415402432, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_745745425", + "type": "text", + "x": 307, + "y": 193, + "width": 160, + "height": 40, + "text": "2. Create pending\nRegistrationRequest", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_405724430", + "originalText": "2. Create pending\nRegistrationRequest", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1256968479, + "version": 1, + "versionNonce": 1566152825, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_950226537", + "type": "arrow", + "x": 297, + "y": 275, + "width": 360, + "height": 0, + "points": [ + [ + 0, + 0 + ], + [ + 360, + 0 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": null, + "boundElements": [ + { + "id": "id_661213676", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1135059127, + "version": 1, + "versionNonce": 1118987313, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_661213676", + "type": "text", + "x": 307, + "y": 253, + "width": 340, + "height": 40, + "text": "3. Publish message\n{request_id, event_id, user_id}", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_950226537", + "originalText": "3. Publish message\n{request_id, event_id, user_id}", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1325878688, + "version": 1, + "versionNonce": 704172848, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_250502322", + "type": "arrow", + "x": 117, + "y": 335, + "width": 180, + "height": 0, + "points": [ + [ + 180, + 0 + ], + [ + 0, + 0 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": null, + "boundElements": [ + { + "id": "id_381377347", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2031648769, + "version": 1, + "versionNonce": 1954585106, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_381377347", + "type": "text", + "x": 127, + "y": 313, + "width": 160, + "height": 40, + "text": "4. 202 Accepted\n+ request_id", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_250502322", + "originalText": "4. 202 Accepted\n+ request_id", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1413495493, + "version": 1, + "versionNonce": 897116390, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_169794101", + "type": "arrow", + "x": 657, + "y": 395, + "width": 180, + "height": 0, + "points": [ + [ + 0, + 0 + ], + [ + 180, + 0 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": null, + "boundElements": [ + { + "id": "id_388948888", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1911495949, + "version": 1, + "versionNonce": 2125874993, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_388948888", + "type": "text", + "x": 667, + "y": 373, + "width": 160, + "height": 40, + "text": "5. Consumer fetches\nmessage", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_169794101", + "originalText": "5. Consumer fetches\nmessage", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1036810200, + "version": 1, + "versionNonce": 192455831, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_507883602", + "type": "arrow", + "x": 477, + "y": 455, + "width": 360, + "height": 0, + "points": [ + [ + 360, + 0 + ], + [ + 0, + 0 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": null, + "boundElements": [ + { + "id": "id_372161493", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 243218126, + "version": 1, + "versionNonce": 363450270, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_372161493", + "type": "text", + "x": 487, + "y": 433, + "width": 340, + "height": 40, + "text": "6. Load pending reg;\ncheck event + duplicates", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_507883602", + "originalText": "6. Load pending reg;\ncheck event + duplicates", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1667716517, + "version": 1, + "versionNonce": 373928545, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_228754657", + "type": "arrow", + "x": 837, + "y": 515, + "width": 180, + "height": 0, + "points": [ + [ + 0, + 0 + ], + [ + 180, + 0 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": null, + "boundElements": [ + { + "id": "id_953805329", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1066326776, + "version": 1, + "versionNonce": 1362790642, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_953805329", + "type": "text", + "x": 847, + "y": 493, + "width": 160, + "height": 40, + "text": "7. TryTakeEventSeat\n(if max_attendees > 0)", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_228754657", + "originalText": "7. TryTakeEventSeat\n(if max_attendees > 0)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1722870536, + "version": 1, + "versionNonce": 1155596140, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_703803469", + "type": "arrow", + "x": 477, + "y": 575, + "width": 360, + "height": 0, + "points": [ + [ + 360, + 0 + ], + [ + 0, + 0 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": null, + "boundElements": [ + { + "id": "id_927603125", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 2083601501, + "version": 1, + "versionNonce": 1465629535, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_927603125", + "type": "text", + "x": 487, + "y": 553, + "width": 340, + "height": 40, + "text": "8. Mark accepted\nor rejected + reason", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_703803469", + "originalText": "8. Mark accepted\nor rejected + reason", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#495057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1684489453, + "version": 1, + "versionNonce": 352955768, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_334532772", + "type": "arrow", + "x": 117, + "y": 645, + "width": 180, + "height": 0, + "points": [ + [ + 0, + 0 + ], + [ + 180, + 0 + ] + ], + "startArrowhead": null, + "endArrowhead": "arrow", + "startBinding": null, + "endBinding": null, + "boundElements": [ + { + "id": "id_497215720", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1897409713, + "version": 1, + "versionNonce": 508105794, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_497215720", + "type": "text", + "x": 127, + "y": 623, + "width": 160, + "height": 40, + "text": "9. Poll GET /events/registrations/:request_id\nuntil not pending", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "id_334532772", + "originalText": "9. Poll GET /events/registrations/:request_id\nuntil not pending", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1551530683, + "version": 1, + "versionNonce": 1791091191, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_317733765", + "type": "rectangle", + "x": 40, + "y": 640, + "width": 500, + "height": 100, + "backgroundColor": "#ffe3e3", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_730007392", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 135546809, + "version": 1, + "versionNonce": 229806699, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_730007392", + "type": "text", + "x": 50, + "y": 648, + "width": 480, + "height": 84, + "text": "Rejection reasons:\ncapacity_full \u00b7 duplicate_user \u00b7 event_closed\nevent_not_found \u00b7 internal_error", + "fontSize": 13, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_317733765", + "originalText": "Rejection reasons:\ncapacity_full \u00b7 duplicate_user \u00b7 event_closed\nevent_not_found \u00b7 internal_error", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 1814021868, + "version": 1, + "versionNonce": 1811941868, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_401911734", + "type": "rectangle", + "x": 560, + "y": 640, + "width": 440, + "height": 100, + "backgroundColor": "#fff3bf", + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "id_348988945", + "type": "text" + } + ] + }, + { + "angle": 0, + "strokeColor": "#1e1e1e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "seed": 670442118, + "version": 1, + "versionNonce": 1869353056, + "isDeleted": false, + "groupIds": [], + "frameId": null, + "link": null, + "locked": false, + "updated": 1, + "id": "id_348988945", + "type": "text", + "x": 570, + "y": 648, + "width": 420, + "height": 84, + "text": "Handler also checks Redis headcount before enqueue.\nIf Kafka publish fails, pending reg is marked internal_error.\nUnlimited events (max_attendees = -1) skip Redis.", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "id_401911734", + "originalText": "Handler also checks Redis headcount before enqueue.\nIf Kafka publish fails, pending reg is marked internal_error.\nUnlimited events (max_attendees = -1) skip Redis.", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/registration_flow.png b/registration_flow.png new file mode 100644 index 0000000..3c2648f Binary files /dev/null and b/registration_flow.png differ diff --git a/system_map.png b/system_map.png new file mode 100644 index 0000000..bb13c43 Binary files /dev/null and b/system_map.png differ