Skip to content

Data layout ​

Each tenant has two directories, both set in tenants.json: data (the database and derived data) and recordings (the original audio). With Docker deployed as in the quickstart, they are data/main and data/main/recordings on the host.

DATA_DIR ​

DATA_DIR is ./data on the host with Docker; with uvx, pip or from source it is your user data directory by default (see Configuration). The tenant main that a first start makes lives under it:

text
<DATA_DIR>/
├── tenants.json
├── models/                         model files (MODELS_DIR)
└── main/                           data directory of tenant main
    ├── live.db                     SQLite database (WAL mode, with live.db-wal and live.db-shm beside it)
    ├── <date>.passes.jsonl         the engine's raw output from each transcription pass
    └── recordings/                 recordings directory of tenant main
        └── chunks/<device>/<date>/<HH>.<ext>

The data directory ​

PathContent
live.dbThe SQLite database, see the table below; its schema is defined in server/alldayrec/db.py
<date>.passes.jsonlThe engine's raw output from each transcription pass
owner-redimnet2.npzThe voiceprint of 「我」 (me)
voices/clips/Voice clips of the speakers
firmware/Recorder firmware packages (only in the first tenant's directory)
live-record.apkThe Android app the server offers at /app.apk (only in the first tenant's directory)

The recordings directory ​

PathContent
chunks/<device>/<date>/<HH>.<ext>One file per device per hour; each piece that arrives is appended to it as is, and its position and length in the file are recorded in the pieces table of live.db. The extension follows the upload's Content-Type: ogg, webm, aac, otherwise bin
rejected/<device>/<start>.<ext>Uploads that failed to decode (the endpoint returned 400), kept as they are for inspection

The tables of live.db ​

TableContent
sentencesFinal sentences: time, speaker, text, source device, engine
draftsDraft-layer sentences (produced only while a page is open), kept after the finals replace them
conversationsConversations: start and end time, participants, seconds of speech, number of sentences, type, device
summariesEach conversation's summary (JSON)
timelinesThe live analysis as it stood when a conversation ended
voicesThe voiceprint and voice clips of each speaker label in each conversation
apartVoices marked 「不是这个人」 (Not this person)
peopleVoiceprints of people with recognized names
enrolledThe sentences each person's voiceprint was learnt from, one row each; an undo or a split takes them back out
aliasesOther names of a person
name_hintsWhat each label was called in a conversation (used only to suggest names)
profilesPeople cards of people with recognized names, each row with its source
piecesThe index of uploaded pieces, which is also the processing queue
feedbackUsers' corrections to summaries
todo_marks「完成」 (Done) or 「不对」 (Wrong) marks on to-dos (new on main, not in v0.1.0)
kvKey-value pairs such as each device's processing progress
device_logDevice events uploaded by the phones, including the recorders' own logs
device_statusRecorder status read by the clients (battery, card, firmware)
callsDuration, result and usage of each ASR and LLM call, without content
balancesPrepaid account balances, recorded hourly
perf_stallsTimes the event loop was held up: when it ended, how many milliseconds, in which functions (only in the first tenant's store; new on main)
perf_samplesThe process, one row a minute: CPU seconds, memory, loop lag, thread pool use, queued pieces, open pages (only in the first tenant's store; new on main)
perf_requestsHTTP requests: one row for each that took 50 ms or more, and each minute one row per method, route and status (new on main)
perf_piecesHow long each step of each final piece and draft pass took: decode, VAD, ASR, voiceprints, store (new on main)

The perf_ tables hold durations and resource use only, never content, and keep 90 days. GET /api/perf?day=YYYY-MM-DD reads one day; python -m alldayrec.perf export <live.db> <YYYY-MM-DD> exports one from a copy of the store.

A voiceprint learnt before enrolled existed is one summary row per person, not tied to sentences. If it took in someone else's voice back then, python -m alldayrec.bank relearn <live.db> recomputes that row from the voices now under the person's name (from live recordings). It only prints, per person, the sentences before and after, the voices used and dropped, and the cosine between the old and the new voiceprint; --apply writes it, and then the server needs a restart (it loads the voiceprints at start). What was learnt sentence by sentence since stays.