Skip to content

feat(notes): add per-user transcript, summary & live-recording storage tables - #6

Open
Rahulkaushik01 wants to merge 3 commits into
devfrom
feat/notes-transcript-storage
Open

feat(notes): add per-user transcript, summary & live-recording storage tables#6
Rahulkaushik01 wants to merge 3 commits into
devfrom
feat/notes-transcript-storage

Conversation

@Rahulkaushik01

Copy link
Copy Markdown
Collaborator

Summary

Adds a new notes Django app with the database schema to store meeting titles,
AI summaries, and live-recording transcripts server-side, scoped per user.
DB layer only — no API/endpoints or runtime behavior change yet; purely additive.

Why

Today transcripts are fetched live from Attendee and never persisted for the desktop
app's users, and meeting "titles" are just URLs. We need durable, per-user storage so a
user sees their meetings on any device, plus a home for LLM-generated titles/summaries
and for live-recording transcripts (which never go through Attendee bots).

What we built — 4 tables (new notes app)

Table Purpose
AppUser Mirror of a team.day user (id, email, name, org). Exists so the other tables can use a real FK + cascade.
Meeting One row per meeting (bot or live): owner, title, source, platform, times, pointer to the Attendee Bot (bot only), summary_state, soft-delete.
LiveUtterance Transcript lines for live recordings (bot transcripts stay in Attendee's Utterance).
MeetingSummary AI summary + action items (one per meeting).

Bot transcripts are pointed to (Meeting.bot), not copied — only new data (titles,
summaries, live transcripts) is stored.

Key decision — real FK to AppUser vs a plain/composite user key

Meeting.owner → AppUser (FK, ON DELETE CASCADE) instead of a plain user_id column or
a composite (user_id, meeting_id) key. Why it's better:

  • DB-enforced cleanup: deleting a user cascades → all their meetings/utterances/summaries
    vanish automatically (the "user removed → no leftover data" guarantee, enforced by the DB,
    not by app code).
  • Integrity: a meeting can't reference a nonexistent user; no orphans.
  • Future-proof: new child tables inherit cascade by adding an FK — no manual delete code.
  • Same read cost: owner_id is an indexed integer — identical query speed to a plain column.
  • Composite key rejected: gives no integrity/cascade benefit and is less efficient — it
    would force every child row (incl. high-volume LiveUtterance) to carry user_id, bloating
    storage/indexes and joins.

Conventions followed

  • Separate notes app — additive only; no existing table is altered.
  • Mirrors Attendee's model style: object_id + prefix (usr_/mtg_/sum_) via the same
    save() generator, created_at/updated_at, IntegerChoices (states) / TextChoices
    (types); the line model LiveUtterance has no object_id (like Utterance).

Edge cases handled at the schema level

  • Atomic, complete user deletion — FK cascade (no leftover, no partial-delete inconsistency).
  • Idempotent live-transcript writessource_uuid unique per meeting (a client session-id
    collision across meetings can't overwrite another meeting's line).
  • Stable ordering(meeting, timestamp_ms, id) tiebreaker (mic + system share one clock).
  • Re-create after soft delete(owner, bot) uniqueness excludes soft-deleted rows, so a
    re-fired webhook doesn't hit a unique violation.
  • STT failures recorded, not lost — nullable transcription/text + failure_data.
  • Survives Attendee delete_dataMeeting.bot is SET_NULL (row + summary remain).

(App-logic edge cases — upsert order, summary-job lifecycle, etc. — come with the follow-up
endpoint PR.)

Files changed

  • notes/models.py — the 4 models
  • notes/migrations/0001_initial.py — initial migration (depends on bots 0087)
  • notes/apps.py, notes/admin.py, notes/__init__.py, notes/migrations/__init__.py
  • attendee/settings/base.py — add "notes" to INSTALLED_APPS
  • version.json1.49.0 → 1.50.0 (minor, per Conventional Commits feat)

Testing & safety

  • Migration applied cleanly locally: Applying notes.0001_initial… OK.
  • Purely additive — only CreateModel/AddIndex/AddConstraint; no AlterField/DeleteModel/
    RunSQL, so it cannot affect existing bots/accounts data.
  • Prod applies migrations automatically on deploy (manage.py migrate --noinput,
    k8s/app/web/deployment.yaml).

Risk / backwards compatibility

  • No runtime/behavior change; no existing model or endpoint touched — new tables only.
  • Requires bots migrations through 0087 (present on dev/prod).

Follow-up (not in this PR)

Auth-server integration: AppUser upsert-on-login, Attendee webhook → Meeting ingestion,
POST /stt/transcribe (live audio → ElevenLabs → LiveUtterance), read endpoints, LLM summary job.

Checklist

  • Conventional Commits PR title
  • version.json bumped (minor)
  • Migration generated & applies cleanly
  • Additive only (no changes to existing tables)
  • Reviewed

@Rahulkaushik01 Rahulkaushik01 self-assigned this Jul 15, 2026
@Rahulkaushik01 Rahulkaushik01 added the enhancement New feature or request label Jul 15, 2026
@Rahulkaushik01
Rahulkaushik01 requested a review from hd1801 July 15, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant