Platform3 · Canonical architecture

Events Alpha Architecture

This page is rendered directly from the committed architecture decisions. Each stable section anchor is part of the public traceability contract.

Source-bound decision record

29 committed decisions · events/alpha

#events_alpha_served_audiences

events alpha served audiences

Unspecified

Decision

students, parents, teachers, and app-builder LLMs building or reading apps that record and query learning, attendance, and discipline moments through plain Events vocabulary over the approved Caliper and Ed-Fi 1EdTech base surfaces

Alternatives and tradeoffs

  • 1EdTech Caliper standards experts only
  • Ed-Fi administrative-record experts only
  • data-warehouse-only analytics users
  • Results-only report builders

Rationale and consequences

the Alpha Events persona needs to record and retrieve moments without learning Caliper Sensor API internals or Ed-Fi administrative collection internals, while still preserving the same database and provenance

#events_alpha_write_granularity

events alpha write granularity

Unspecified

Decision

SHIP + DEFER: Ship one bulk-capable collection create operation for one or many Caliper-backed learning activity events; defer separate per-event create, PUT, PATCH, DELETE, and Alpha attendance/discipline write routes. Core attendance and discipline writes route to the Ed-Fi 1EdTech base surface. Re-open trigger: Re-open separate per-event mutation or Alpha attendance/discipline writes only when three distinct integrator decisions in 90 days show that one-array create plus Ed-Fi base writes block valid Alpha app-builder workflows.

Alternatives and tradeoffs

  • Separate single-event and batch write endpoints
  • Direct per-event PUT/PATCH/DELETE
  • Raw Caliper envelope only
  • Alpha attendance/discipline writes now

Rationale and consequences

pinned by eaitd-101 so downstream deliverables do not invent write granularity behavior

#events_alpha_read_shape

events alpha read shape

Unspecified

Decision

SHIP: Ship list plus detail for learning events, attendance events, discipline events, and safe activity sources; no public raw batch, raw entity, conformance, or generic Ed-Fi sub-collections. Re-open trigger: Re-open sub-collections only when an approved customer website workflow needs a bounded drilldown that cannot be expressed as event detail or source detail.

Alternatives and tradeoffs

  • Detail-only exact lookup
  • List + detail + raw sub-collections
  • Direct table browser

Rationale and consequences

pinned by eaitd-102 so downstream deliverables do not invent read shape behavior

#events_alpha_query_model

events alpha query model

Unspecified

Decision

SHIP + DEFER: Ship filter + cursor paging + modifiedSince over learning, attendance, and discipline event streams; defer arbitrary SQL-style query, aggregations, joins, and full-text search. Re-open trigger: Re-open aggregations or search when three accepted integration reports in 90 days need the same aggregate and it belongs in Events rather than Results or Content.

Alternatives and tradeoffs

  • No filters
  • Filter + sort without cursors
  • SQL-like query language
  • Client-side raw export filtering

Rationale and consequences

pinned by eaitd-103 so downstream deliverables do not invent query model behavior

#events_alpha_concurrency_model

events alpha concurrency model

Unspecified

Decision

DEFER: No If-Match or ETag concurrency model ships because accepted events are immutable append records. Re-open trigger: Re-open only with the first approved public Events update route or correction workflow that changes an existing event row.

Alternatives and tradeoffs

  • If-Match per event
  • Bulk If-Match
  • Last-write-wins mutable event edits

Rationale and consequences

pinned by eaitd-104 so downstream deliverables do not invent concurrency model behavior

#events_alpha_idempotency_model

events alpha idempotency model

Unspecified

Decision

SHIP: Ship sourceEventId plus inherited Caliper canonical hashes and optional platform Idempotency-Key; conflict when the same key is reused with different content. Re-open trigger: Re-open only if live duplicate incidents show sourceEventId plus canonical hash dedupe is insufficient for valid Alpha event writers.

Alternatives and tradeoffs

  • No idempotency
  • Required Idempotency-Key only
  • Database UUID-only duplicate handling

Rationale and consequences

pinned by eaitd-105 so downstream deliverables do not invent idempotency model behavior

#events_alpha_auth_shape

events alpha auth shape

Unspecified

Decision

SHIP: Ship platform Bearer JWT auth with tenant claim, role/roles, Events scopes, and optional student/org/class/content boundary claims for read filtering. Re-open trigger: Re-open authorization claims only when People & Orgs or platform architecture pins a new cross-module claim shape.

Alternatives and tradeoffs

  • Role-only JWT
  • Public read endpoints
  • API keys without tenant claims
  • Caliper sensor credentials or Ed-Fi source credentials as user auth

Rationale and consequences

pinned by eaitd-106 so downstream deliverables do not invent auth shape behavior

#events_alpha_eventing_model

events alpha eventing model

Unspecified

Decision

SHIP + DEFER: Ship poll-based activity, attendance, and discipline stream reads with modifiedSince; defer outbound webhooks and push streams. Re-open trigger: Re-open webhooks when three integrations in 90 days cannot complete their job with modifiedSince polling or when platform pins a shared webhook primitive.

Alternatives and tradeoffs

  • No polling
  • Webhooks now
  • Server-sent event stream now

Rationale and consequences

pinned by eaitd-107 so downstream deliverables do not invent eventing model behavior

#events_alpha_error_envelope

events alpha error envelope

Unspecified

Decision

SHIP: Ship shared RFC 7807 Problem JSON with stable codes, plain-language titles/details, safe invalid-parameter paths, and architecture/data-dictionary links. Re-open trigger: Re-open only if platform PITD-006 changes the shared Problem contract or SDK generation needs a cross-module problem-code registry.

Alternatives and tradeoffs

  • Plain prose errors
  • Raw Caliper or Ed-Fi validator errors only
  • Custom Alpha-only error envelope

Rationale and consequences

pinned by eaitd-108 so downstream deliverables do not invent error envelope behavior

#events_alpha_tenant_routing

events alpha tenant routing

Unspecified

Decision

SHIP: Ship platform tenant routing by X-Timeback-Tenant header plus matching JWT tenant claim; no tenant path prefix and no payload-inferred tenant. Re-open trigger: Re-open only if platform-wide routing changes or an approved Alpha customer website workflow requires tenant path routing across modules.

Alternatives and tradeoffs

  • Tenant in URL
  • JWT-only hidden tenant
  • Tenant inferred from actor/group/content references

Rationale and consequences

pinned by eaitd-109 so downstream deliverables do not invent tenant routing behavior

#events_alpha_conformance_evidence

events alpha conformance evidence

Unspecified

Decision

SHIP + DEFER: Ship local docs, alias-map, live API, surface QC, integration, skill-pack evidence, and attendance/discipline three-way convergence probes; defer public Alpha conformance-run mutation and official 1EdTech certification claims. Re-open trigger: Re-open official certification only when an external certification run exists; re-open public evidence APIs only when a customer job needs evidence beyond hosted docs and surface QC.

Alternatives and tradeoffs

  • No evidence
  • Claim official certification from local tests
  • Public conformance runner

Rationale and consequences

pinned by eaitd-110 so downstream deliverables do not invent conformance evidence behavior

#events_alpha_privacy_retention

events alpha privacy retention

Unspecified

Decision

SHIP + DEFER: Ship tenant/role-scoped redacted projections and sensitive raw-payload preservation for Caliper activity plus Ed-Fi attendance/discipline; defer Events-specific public DELETE and age-based retention endpoints. Re-open trigger: Re-open public deletion or retention endpoints when platform privacy policy names retention periods or a legal/compliance workflow requires public erasure over Events data.

Alternatives and tradeoffs

  • Raw payloads in public Alpha
  • Drop all raw payloads
  • Events-local retention policy

Rationale and consequences

pinned by eaitd-111 so downstream deliverables do not invent privacy / retention behavior

#events_alpha_list_endpoints

events alpha list endpoints

Unspecified

Decision

SHIP + DEFER: Ship Events, attendance-events, discipline-events, and safe activity-source list endpoints; defer one list endpoint per Caliper table, one list endpoint per generic Ed-Fi collection, and raw entity/envelope/conformance lists. Re-open trigger: Re-open additional collection lists only when a documented Alpha workflow cannot be expressed through /events, /attendance-events, /discipline-events, or /activity-sources.

Alternatives and tradeoffs

  • Write-and-remember only
  • One list endpoint per upstream table
  • Direct generic table browsing

Rationale and consequences

pinned by eaitd-112 so downstream deliverables do not invent list endpoints behavior

#events_alpha_eaitd-001

events alpha eaitd 001

Unspecified

Decision

Restrict + rename: Events module boundary over shared Caliper persistence

Alternatives and tradeoffs

  • Expose Caliper unchanged
  • Create a new alpha.events database independent of Caliper
  • Flatten all event, content, result, and roster facts into one Alpha activity table
  • Add alpha_* projection columns directly to caliper.event

Rationale and consequences

Events is a facade over caliper.* rows, not a second database or a Results shortcut.

#events_alpha_eaitd-002

events alpha eaitd 002

Unspecified

Decision

Rename: Plain event vocabulary and alias map

Alternatives and tradeoffs

  • Keep Caliper names in Alpha
  • Hide all Caliper names
  • Use a prose-only glossary

Rationale and consequences

Every Alpha name maps to one approved Caliper or Ed-Fi 1EdTech source or is explicitly marked as an extension.

#events_alpha_eaitd-003

events alpha eaitd 003

Unspecified

Decision

Restrict: Event-result-content boundary

Alternatives and tradeoffs

  • Let each event carry score and mastery fields for convenience
  • Forbid result references from events entirely
  • Move all attempts and submissions to Results only

Rationale and consequences

Events may point to Results and Content but cannot become those records.

#events_alpha_eaitd-004

events alpha eaitd 004

Unspecified

Decision

Rename + restrict + register: Activity source registry. POST /activity-sources is the tenant-scoped create door; the platform generates activitySource.id, (tenantId, sourceIri) is the idempotent natural key, identical retries return the existing registration, and different identity fields for the same sourceIri return 409. Registration requires events:sources:write or an approved source/operator role and never accepts or returns credentialRef, metadata, tokens, or secret values.

Alternatives and tradeoffs

  • Expose caliper.sensor unchanged
  • Hide sources entirely
  • Store source API keys directly on activitySource
  • Keep registration as an undocumented operator-only database or startup-seed action
  • Let producer apps choose activitySource.id by deriving it from sourceIri

Rationale and consequences

Sensor becomes activitySource; producers receive one governed registration door without learning Caliper storage or source secrets, and the platform-owned UUID remains stable across safe retries.

#events_alpha_eaitd-005

events alpha eaitd 005

Unspecified

Decision

Rename + restrict: Plain event ingest through Caliper envelopes

Alternatives and tradeoffs

  • Require raw Caliper Sensor envelopes from Alpha apps
  • Add separate single-event and batch endpoints
  • Let apps write directly to caliper.event rows

Rationale and consequences

Alpha event writers use school-language event batches that translate to Caliper Sensor API records.

#events_alpha_eaitd-006

events alpha eaitd 006

Unspecified

Decision

Extend + restrict: Real relationship links

Alternatives and tradeoffs

  • Store every relationship as a governed tag
  • Parse Caliper actor/object/entity IRIs during every read
  • Flatten every possible Caliper entity subclass into columns
  • Store copied actor/object/group JSON in alpha.event_extension for convenience

Rationale and consequences

Links to students, content, orgs, apps, and results are typed relationships, not loose tags.

#events_alpha_eaitd-007

events alpha eaitd 007

Unspecified

Decision

Extend + restrict: Typed event kind taxonomy

Alternatives and tradeoffs

  • Expose only Caliper event_type/profile/action
  • Infer event kind from event names or URLs at read time
  • Let every app invent arbitrary event kind strings

Rationale and consequences

event.kind is governed and computed from typed Caliper fields at write/normalization time.

#events_alpha_eaitd-008

events alpha eaitd 008

Unspecified

Decision

Cut: Cut raw transport and conformance internals from public Alpha

Alternatives and tradeoffs

  • Expose all Caliper rows with friendly labels
  • Delete raw transport and conformance evidence from storage
  • Expose raw data only behind a boolean includeRaw parameter

Rationale and consequences

Raw JSON-LD, canonical hashes, envelope internals, and conformance-run mutations are not public Alpha resources.

#events_alpha_eaitd-009

events alpha eaitd 009

Unspecified

Decision

Extend: Activity stream read model

Alternatives and tradeoffs

  • Keep the 1EdTech exact lookup only
  • Ship a full analytics query language
  • Require consumers to export raw events and filter locally

Rationale and consequences

Alpha ships a cursor-filtered stream and event detail because teachers and app-builder LLMs need to retrieve moments.

#events_alpha_eaitd-010

events alpha eaitd 010

Unspecified

Decision

Restrict: Privacy, redaction, and retention

Alternatives and tradeoffs

  • Reject all PII-bearing Caliper payloads
  • Expose raw payloads to anyone with events:read
  • Invent Events-specific retention and deletion policy now

Rationale and consequences

Alpha redacts secondary surfaces and leaves erasure/retention policy to platform-level commitments.

#events_alpha_eaitd-011

events alpha eaitd 011

Unspecified

Decision

Extend: Provenance and data-dictionary generation

Alternatives and tradeoffs

  • Trust prose-only architecture
  • Duplicate the full Caliper data dictionary into Alpha
  • Let data dictionary authors infer provenance later

Rationale and consequences

Every Alpha object, field, endpoint, enum, and behavior links to this architecture and the 1EdTech source.

#events_alpha_eaitd-012

events alpha eaitd 012

Unspecified

Decision

Restrict + extend: Alpha storage gate: views over Caliper and Ed-Fi, extension sidecars only

Alternatives and tradeoffs

  • Own Alpha tables for event, attendanceEvent, disciplineEvent, activitySource, eventBatch, eventThing, and eventLink
  • Add Alpha projection columns directly to caliper.event or edfi.canonical_record
  • Views over Caliper/Ed-Fi plus extension sidecars

Rationale and consequences

Rename/cut/restrict are SQL views; only new Alpha event facts get sidecar tables with no 1EdTech-sourced columns.

#events_alpha_eaitd-013

events alpha eaitd 013

Unspecified

Decision

Restrict + rename: Second upstream: Ed-Fi event-shaped administrative records

Alternatives and tradeoffs

  • Keep Events Caliper-only
  • Create a separate Attendance or Discipline Alpha module
  • Surface every Ed-Fi domain in Events
  • Copy Ed-Fi rows into Alpha event tables

Rationale and consequences

Attendance and discipline are genuine moments, while guardians, staff, programs, and transcripts stay in sibling modules.

#events_alpha_eaitd-014

events alpha eaitd 014

Unspecified

Decision

Rename + restrict: Attendance event view over Ed-Fi attendance records

Alternatives and tradeoffs

  • Expose Ed-Fi attendance collections unchanged in Alpha Events
  • Store alpha.attendance_event as an Alpha table copied from Ed-Fi
  • Compute attendance from Caliper login or session events
  • Leave attendance in an Ed-Fi-only module

Rationale and consequences

StudentSchoolAttendanceEvent and StudentSectionAttendanceEvent become alpha.attendance_event views over Ed-Fi canonical records.

#events_alpha_eaitd-015

events alpha eaitd 015

Unspecified

Decision

Rename + restrict: Discipline event view over Ed-Fi incidents and behavior associations

Alternatives and tradeoffs

  • Expose only DisciplineIncident rows
  • Expose only StudentDisciplineIncidentBehaviorAssociation rows
  • Copy incident and association payloads into an Alpha table
  • Leave discipline out of Events as an Ed-Fi administrative detail

Rationale and consequences

DisciplineIncident plus StudentDisciplineIncidentBehaviorAssociation becomes alpha.discipline_event without copying Ed-Fi payloads.

#events_alpha_eaitd-016

events alpha eaitd 016

Unspecified

Decision

Restrict: Ed-Fi raw-read guardrails and convergence probes

Alternatives and tradeoffs

  • Trust the API and leave raw rules in Ed-Fi docs only
  • Tell raw consumers to query alpha.attendance_event and alpha.discipline_event only
  • Let the skill pack perform soft-delete, descriptor, and draft cleanup
  • Expose raw Ed-Fi collections with no convergence questions

Rationale and consequences

Every API guardrail for attendance and discipline must be documented as a raw-DB rule and tested by three-way convergence.