Skip to main content
Engineering/snap-document

SNAP Document

You need to document APIs, data, integrations, events, stories, and risks per bounded context.

Use this when you have a Boris model (or at minimum, identified bounded contexts) and need to capture detailed architecture information for each context. SNAP documents the six categories that turn a conceptual model into an actionable implementation plan: APIs, Data, External Systems/UI, Pub/Sub Events, Stories, and Risks.

Full guide: See the Architecture Discovery Workshop Playbook for the complete method.

Process

Step 1: Gather inputs

Ask the user:

  1. Boris model outputs — services, interactions, API candidates, and open questions. If running as part of /architecture-discovery, these carry forward automatically.
  2. Bounded contexts to document — all of them, or a specific subset?
  3. Depth — full SNAP (all 6 categories) or focused (APIs + Data + Risks only)?
  4. Backlog destination — should stories be pushed to Linear, Jira, Notion, or kept in markdown?
  5. Output destination — conversation only, Miro, Notion, or file?

Step 2: Create SNAP sheets

For each bounded context, generate a SNAP sheet by asking these questions:

APIs:

  • What APIs must this context expose?
  • Who are the consumers?
  • What are the key operations (CRUD, search, workflow)?

Data:

  • What data does this context own?
  • What are the key entities and their relationships?
  • What data does it NOT own but needs access to?

External Systems / UI:

  • Does this context integrate with external systems?
  • Does it expose a user interface?
  • What protocols or standards are required?

Pub/Sub (Events):

  • What events does this context publish?
  • What events does it subscribe to?
  • What happens if an event is missed or delayed?

Stories:

  • What backlog work items emerge from this context?
  • What's the first thin slice to implement?
  • What spikes or investigations are needed?

Risks:

  • What architectural risks exist?
  • What delivery risks (skills, timeline, dependencies)?
  • What unknowns need to be resolved before implementation?

Step 3: Generate SNAP sheets

Use the SNAP template to produce the deliverable:


SNAP: (Bounded Context Name)

Domain: (Parent domain) Owner: (Team or individual) Source: Boris model (date)

APIs

APIMethodConsumer(s)DescriptionStatus
(Endpoint or operation)GET/POST/PUT/DELETE(Who calls it)(What it does)Proposed/Existing

Data

EntityKey AttributesOwned ByAccessed ByNotes
(Entity name)(Key fields)This context(Other contexts)(Constraints)

External Systems / UI

SystemIntegration TypeDirectionProtocolNotes
(System name)API/File/Event/UIInbound/Outbound/BothREST/gRPC/File/etc.(Details)

Pub/Sub Events

EventTypeDirectionPayload SummaryConsumer(s)
(Event name)Domain/IntegrationPublish/Subscribe(Key data)(Who listens)

Stories

StoryPriorityEstimateDependenciesNotes
(Story title)High/Med/LowS/M/L(Blockers)(Context)

Risks

RiskLikelihoodImpactMitigationOwner
(Risk description)High/Med/LowHigh/Med/Low(Proposed mitigation)(Who owns it)

Repeat the template for each bounded context.

Step 4: Identify gaps

After completing all SNAP sheets, explicitly list:

  • APIs referenced by consumers but not yet defined by providers
  • Data claimed by multiple contexts (ownership conflicts)
  • Events published but not consumed (dead letters)
  • Events consumed but not published (missing producers)
  • Stories with unresolved dependencies

Step 5: Generate consolidated backlog

Collect all stories from SNAP sheets into a single prioritized backlog:

#StoryContextPriorityDependenciesNotes
1(Story)(Context)(Priority)(Deps)(Notes)

Step 6: Push to backlog tool (optional)

If the user specified a backlog destination in Step 1:

  • Linear — use save_issue for each story, with labels for the bounded context
  • Notion — use notion-create-pages with a database parent for structured backlog
  • Miro — use table_create for the consolidated backlog table
  • File — save to ./output/snap/(domain-name)-snap.md

Step 7: Review

Ask the user:

  • Are there SNAP categories with too many unknowns?
  • Should any bounded context be split further?
  • Which stories should be tackled first?
  • Are the risks acceptable, or do any need immediate spikes?
  • Is this ready for team review, or do we need another pass?

Uncertainty Policy

TopicToleranceAction
API contract details (endpoints, payloads)LowSTOP and ask — wrong contracts create integration failures
Data ownership per bounded contextLowSTOP and ask — ambiguous ownership causes data consistency bugs
Story scope and acceptance criteriaMediumAssume + flag [ASSUMED] — stories are refined during backlog grooming
Risk severity and mitigationMediumAssume + flag [ASSUMED] — team triages during review
Integration event schemasMediumAssume + flag [ASSUMED] — schemas evolve, direction matters more
Story priority orderingHighBest guess — backlog is a starting point for team discussion

Default: STOP and ask when a topic is not listed above.

Related skills

  • /event-storm — first stage: discover domain events and bounded contexts
  • /boris-model — previous stage: model service relationships
  • /architecture-discovery — skill set that chains all three stages
  • /story-write — flesh out individual stories from the SNAP backlog
  • /api-docs-design — when API documentation needs to go beyond architecture contracts to developer-facing reference and guides

Output locations

FormatLocationNotes
MarkdownConversation or saved fileAlways produced. Source of truth.
LinearUser's Linear workspaceStories as issues via Linear MCP.
Notion pageUser's specified Notion locationVia Notion MCP.
Miro tableUser's specified Miro boardVia Miro MCP.
File./output/snap/(domain)-snap.mdLocal file.

Example Output

Input

  • Boris model outputs: Three bounded contexts identified for Meridian Health's patient engagement platform — Appointment Scheduling, Notifications, and Patient Identity. Key interactions: Scheduling publishes AppointmentBooked and AppointmentCancelled; Notifications subscribes to both; Patient Identity is called synchronously by Scheduling to resolve patient records. Open question: who owns preferred contact channel — Scheduling or Identity?
  • Bounded contexts to document: All three
  • Depth: Full SNAP (all 6 categories)
  • Backlog destination: Linear
  • Output destination: Conversation + file saved to ./output/snap/meridian-patient-engagement-snap.md

Output (abbreviated)

SNAP: Meridian Health — Patient Engagement Platform

Boris model date: 2025-06-10 Output file: ./output/snap/meridian-patient-engagement-snap.md


SNAP: Appointment Scheduling

Domain: Patient Engagement Owner: Care Coordination Squad Source: Boris model (2025-06-10)

APIs

APIMethodConsumer(s)DescriptionStatus
/appointmentsPOSTPatient Portal UI, Mobile AppBook a new appointmentProposed
/appointments/{id}PUTPatient Portal UIReschedule or update appointmentProposed
/appointments/{id}DELETEPatient Portal UI, Call Center AppCancel an appointmentProposed
/appointments?patientId=GETCare Coordination UIRetrieve appointment history for a patientProposed
/slots?providerId=&date=GETPatient Portal UI, Mobile AppQuery available slots for a providerProposed

Data

EntityKey AttributesOwned ByAccessed ByNotes
Appointmentid, patientId, providerId, slotId, status, createdAtAppointment SchedulingNotifications (read via event)Status enum: BOOKED, CANCELLED, COMPLETED, NO_SHOW
Slotid, providerId, startTime, endTime, locationId, availableAppointment SchedulingPatient Portal UIAvailability updated on booking/cancellation
Providerid, name, specialty, locationIds[ASSUMED] Appointment SchedulingCare Coordination UIMay belong to a separate Staff context — flag for review

⚠️ Ownership conflict: preferredContactChannel (email/SMS/push) is currently unassigned. Both Scheduling and Patient Identity have a claim. Decision required before sprint 1.

External Systems / UI

SystemIntegration TypeDirectionProtocolNotes
Patient Portal (Web)UIInboundREST/HTTPSPrimary booking surface
Mobile App (iOS/Android)UIInboundREST/HTTPSUses same API surface as Portal
EHR — CernerAPIOutboundHL7 FHIR R4Slot availability and provider data sync; nightly batch + on-demand
Call Center AppUIInboundREST/HTTPSRead/cancel only; no booking

Pub/Sub Events

EventTypeDirectionPayload SummaryConsumer(s)
AppointmentBookedDomainPublishappointmentId, patientId, providerId, slotStart, locationTypeNotifications, Analytics (future)
AppointmentCancelledDomainPublishappointmentId, patientId, cancelledBy, reason, originalSlotStartNotifications, Slot Availability (internal)
AppointmentRescheduledDomainPublishappointmentId, oldSlotStart, newSlotStartNotifications [ASSUMED] — confirm with Notifications squad
PatientVerifiedIntegrationSubscribepatientId, identityConfirmed, preferredNamePatient Identity

Stories

StoryPriorityEstimateDependenciesNotes
Implement POST /appointments with slot lockingHighLPatient Identity API availableThin slice: book, confirm, emit event
Implement GET /slots with real-time Cerner syncHighLCerner FHIR sandbox accessSpike needed first (see Risks)
Implement cancellation flow + AppointmentCancelled eventHighMSlot service, event bus configuredInclude reason codes
Spike: FHIR R4 slot sync latency and rate limitsHighSCerner sandbox credentialsMust resolve before slot story
Implement appointment history endpointMedSNoneFilter by date range, status
Add AppointmentRescheduled eventMedMBooking + cancellation storiesConfirm payload with Notifications

Risks

RiskLikelihoodImpactMitigationOwner
Cerner FHIR rate limits block real-time slot availabilityHighHighSpike in sprint 1; design local cache with TTL fallbackPlatform Lead
preferredContactChannel ownership unresolved — dual-write riskHighHighArchitecture decision required before sprint 1 kickoffDomain Architect
Patient Identity latency causes booking failures under loadMedHighAsync verification fallback + circuit breaker pattern [ASSUMED]Care Coordination TL
EHR sandbox unavailable for dev/testMedMedMock FHIR server (HAPI) in local environmentDevOps

SNAP: Notifications

Domain: Patient Engagement Owner: Communication Platform Squad Source: Boris model (2025-06-10)

APIs

APIMethodConsumer(s)DescriptionStatus
/notifications/preferences/{patientId}GET/PUTPatient Portal UIManage patient notification opt-insProposed
/notifications/sendPOSTInternal services onlyTrigger ad-hoc notification (admin use)Proposed

Data

EntityKey AttributesOwned ByAccessed ByNotes
NotificationPreferencepatientId, channels[], timezone, optOutAtNotificationsPatient Portal UIDepends on preferredContactChannel ownership resolution
NotificationLogid, patientId, type, channel, sentAt, status, messageRefNotificationsCompliance/AuditRetention: 7 years per HIPAA

Pub/Sub Events

EventTypeDirectionPayload SummaryConsumer(s)
AppointmentBookedDomainSubscribeappointmentId, patientId, slotStartFrom Scheduling
AppointmentCancelledDomainSubscribeappointmentId, patientId, reasonFrom Scheduling
NotificationSentIntegrationPublishnotificationId, patientId, channel, timestampAudit/Compliance [ASSUMED]

⚠️ AppointmentRescheduled event is consumed here but not yet confirmed as published by Scheduling. Flagged as missing producer.

Risks

RiskLikelihoodImpactMitigationOwner
SMS delivery failures not surfaced to patientMedHighImplement delivery receipt webhook from Twilio; retry logic with fallback to emailComms Platform TL
HIPAA PHI in notification payloadsHighHighTokenize patientId in event payloads; retrieve PII at send time only [ASSUMED]Security Architect

SNAP: Patient Identity

Domain: Patient Engagement Owner: Identity & Access Squad Source: Boris model (2025-06-10)

APIs

APIMethodConsumer(s)DescriptionStatus
/patients/{id}/verifyPOSTAppointment Scheduling