Atlas Plan

Data Model

Data Model

Core data model for the Atlas system. All entity names and field names follow the terminology defined in glossary.md.

Tables are grouped by domain. The group name is used as the table prefix.

Scope note: This document covers the operational layer only — the 38 LibSQL tables managed by Drizzle ORM, used for individual record lookup and dashboard drill-down. The analytical layer (DuckDB raw, staging, intermediate, and mart tables) is defined in dbt models and documented in analytics.md.


Table Groups

GroupPrefixContents
Corecore_Org hierarchy: group, entity, unit
Databasedb_Master data: people, organizations, accounts, relations, and their lookups
Catalogcatalog_Product catalog: brands, items, variants, pricing
Commercecommerce_Orders and order classification lookups
Financefinance_Transactions and payment lookups
Marketingmarketing_Channel types, channels, segments, agendas, activities, and all join tables
Targettarget_Goals and metric lookups

Entity Relationship Diagram (Summary)

PKs and FKs only. Full field details are in the entity sections below and in the detailed diagram at the bottom.


core_ — Core

core_group

The top-level parent organization. All entities and their units ultimately belong to a Group. In the current deployment, GNY (Grup Neutron Yogyakarta) is the only Group.

FieldTypeRequiredNotes
idulidyesPK
namestringyesShort name, e.g. GNY
full_namestringnoe.g. Grup Neutron Yogyakarta

core_entity

A legal or business entity under a Group. Each Entity operates independently with its own units, targets, and reporting scope. IONs and EPN are the current entities under GNY. All data in the system is scoped to an Entity.

FieldTypeRequiredNotes
idulidyesPK
group_idulidyesFK → core_group
codestringyese.g. IONS, EPN — unique within a Group
namestringyes
full_namestringno

core_unit

An operating unit within an Entity. A Unit owns products, fulfills orders, and reports revenue independently. Units are the primary dimension for financial reporting and target-setting. Examples: TM, WLC_ENGLISH, WLC_NON_ENGLISH, REAL, NP, ICC, ICA, DTC.

FieldTypeRequiredNotes
idulidyesPK
entity_idulidyesFK → core_entity
codestringyese.g. TM, WLC_ENGLISH — unique within an Entity
namestringyesDisplay name

db_ — Database

db_sex

Biological sex of a Person.

FieldTypeRequiredNotes
idulidyesPK
namestringyesMale, Female
source_termstringnoL, P

db_organization_level

The classification of an Organization by education or institutional level.

FieldTypeRequiredNotes
idulidyesPK
namestringyesElementary, Middle School, High School, University, Institution, General Public
source_termstringnoTK / SD, SMP / MTs, SMA / SMK / MAN, Universitas / Perguruan Tinggi, Instansi, Lain-Lain / Umum

db_relation_type

The nature of the relationship between two Persons.

FieldTypeRequiredNotes
idulidyesPK
namestringyesGuardian, Parent, Spouse, Employer, Emergency Contact
source_termstringno

db_account_type

The billing classification of an Account.

FieldTypeRequiredNotes
idulidyesPK
namestringyesIndividual, Household, Corporate
source_termstringno

db_organization

A school, university, company, or institution that a Person is affiliated with. Organizations are used for school segmentation reporting (School Progress) — tracking which institutions students come from and how that changes year over year.

FieldTypeRequiredNotes
idulidyesPK
namestringyese.g. Universitas Gadjah Mada, SMA N 1 Yogyakarta
level_idulidyesFK → db_organization_level
entity_idulidnonullable — scopes the organization to a specific Entity if needed

db_person

An individual human in the system. A Person can play different roles depending on context: as a Participant (attending a program), a Guardian (parent paying for a child), or a Payer. The same physical person may appear in multiple roles across different orders. Relationships between Persons (e.g. parent-child) are captured via db_relation.

FieldTypeRequiredNotes
idulidyesPK
first_namestringyes
last_namestringno
date_of_birthdatenoT/T/L (Tanggal Lahir)
birth_placestringnoT/T/L (Tempat Lahir)
sex_idulidnoFK → db_sex
national_idstringnoKTP/ID — Indonesian national ID
phonestringno
emailstringno
addressstringno
organization_idulidnoFK → db_organization
is_verifiedboolnodefault false

db_relation

A directed relationship between two Persons. Used to capture family, employment, or care relationships that exist independently of any order. For example, a parent-child pair is recorded here so the system knows who is guardian of whom regardless of purchase history.

FieldTypeRequiredNotes
idulidyesPK
from_person_idulidyesFK → db_person — the person in the active role (e.g. the guardian)
to_person_idulidyesFK → db_person — the person in the passive role (e.g. the child)
relation_type_idulidyesFK → db_relation_type
notesstringno

db_account

The billing entity for an Order — the party who is financially responsible for a payment. An Account may be an individual adult (paying for themselves), a household (a parent paying for a child), or a corporate entity (a company paying for employees). One Person may be linked to multiple Accounts.

FieldTypeRequiredNotes
idulidyesPK
account_type_idulidyesFK → db_account_type
namestringyesDisplay name for the account
person_idulidnoFK → db_person — main contact for this account
organization_idulidnoFK → db_organization — for Corporate accounts

catalog_ — Catalog

catalog_item_type

The delivery format of a catalog item.

FieldTypeRequiredNotes
idulidyesPK
namestringyesRegular, Private, Other
source_termstringnoReguler, Privat

catalog_brand

A market-facing brand identity that may span one or more Units. For example, the WLC brand covers both WLC_ENGLISH and WLC_NON_ENGLISH units. Items belong to a Brand; Units fulfill the orders. The relationship between Brand and Unit is managed via the catalog_brand_unit join table.

FieldTypeRequiredNotes
idulidyesPK
namestringyese.g. WLC, True Mandarin, REAL
descriptionstringno

catalog_brand_unit

Join table linking Brands to Units (M2M). A Brand can be associated with multiple Units, and a Unit can carry multiple Brands.

FieldTypeRequiredNotes
brand_idulidyesFK → catalog_brand
unit_idulidyesFK → core_unit

catalog_item

A service or course offering in the catalog. Items belong to both a Brand (market-facing identity) and a Unit (operational owner). Each item has a type (delivery format) and a category (for grouping in reports). Examples: Basic Adults (TM / True Mandarin), German Regular (WLC_NON_ENGLISH / WLC), IELTS Prep (REAL).

FieldTypeRequiredNotes
idulidyesPK
brand_idulidyesFK → catalog_brand
unit_idulidyesFK → core_unit
namestringyese.g. Basic Adults, German Regular, IELTS Prep
categorystringnoe.g. Mandarin Adults, WLC Non-English
item_type_idulidyesFK → catalog_item_type
source_termstringnoOriginal name in source data

catalog_item_variant

A specific level or pricing tier within a catalog item. Variants represent both curriculum levels (e.g. Dragon Basic 1, Dragon Basic 2, German A1.1) and pricing tiers (e.g. Regular, Platinum). An Order references the specific variant purchased.

FieldTypeRequiredNotes
idulidyesPK
item_idulidyesFK → catalog_item
namestringyese.g. Dragon Basic 2, German A1.1, Platinum Basic Adults
levelstringnoCurriculum level label, e.g. A1.1, Basic, Intermediate
tierstringnoPricing tier label, e.g. Regular, Platinum, Gold
source_termstringnoOriginal name in source data, e.g. KELAS/LEVEL value

catalog_price_list

A named set of prices valid for a given period. Price lists allow different pricing strategies (standard, platinum, corporate) and can be scoped to a specific Unit or apply globally across an Entity.

FieldTypeRequiredNotes
idulidyesPK
entity_idulidyesFK → core_entity
unit_idulidnoFK → core_unit — null means entity-wide price list
namestringyese.g. Standard 2026, Platinum Tier, Corporate Rate
currencystringyese.g. IDR
valid_fromdateyes
valid_todatenonull means currently active

catalog_price

A specific price for an item or variant within a price list. Either item_id or variant_id must be set — a price can be set at the item level (applies to all variants) or overridden at the variant level.

FieldTypeRequiredNotes
idulidyesPK
price_list_idulidyesFK → catalog_price_list
item_idulidnoFK → catalog_item — item-level price
variant_idulidnoFK → catalog_item_variant — variant-level price overrides item-level
amountdecimalyesIn the currency of the price list

commerce_ — Commerce

commerce_order_type

The nature of a commercial transaction on an Order.

FieldTypeRequiredNotes
idulidyesPK
namestringyesEnrollment, Book Sale, Event Fee, Institution Fee, Other
source_termstringno

commerce_customer_type

The classification of a customer's relationship history at the time of an Order.

FieldTypeRequiredNotes
idulidyesPK
namestringyesNew, Renewal, Alumni
source_termstringnoSiswa Baru, Siswa Lanjut, Siswa Alumni

commerce_order

A single commercial transaction between an Account and a Unit for an item. Orders are the central record linking people, products, and money. The order_type distinguishes enrollments (which require a Participant) from other purchase types such as book sales or event fees. customer_type is stored for performance and audit but can always be recomputed from a Person's order history.

FieldTypeRequiredNotes
idulidyesPK
entity_idulidyesFK → core_entity
unit_idulidyesFK → core_unit
account_idulidyesFK → db_account — who pays
participant_idulidnoFK → db_person — who attends; required for Enrollment orders
item_idulidnoFK → catalog_item — null for ad-hoc orders
variant_idulidnoFK → catalog_item_variant — specific level or tier purchased
order_type_idulidyesFK → commerce_order_type
customer_type_idulidnoFK → commerce_customer_type — stored, also computable from history
period_yearintnoIntake year
period_monthintnoIntake month
channel_idulidnoFK → marketing_channel — acquisition source
receipt_numberstringnoe.g. TM.026.02.0001
notesstringno
source_filestringnoAudit — name of the source file
source_sheetstringnoAudit — sheet name within the source file

finance_ — Finance

finance_payment_method

How a payment was physically made.

FieldTypeRequiredNotes
idulidyesPK
namestringyesCash, Transfer, EDC, QRIS
source_termstringnoTunai, Transfer, EDC, QRIS

finance_payment_status

The settlement state of a Transaction.

FieldTypeRequiredNotes
idulidyesPK
namestringyesPaid in Full, Installment, Settlement
source_termstringnoLunas, Angsuran / Angsur, Pelunasan

finance_transaction

A single payment event against an Order. One Order may have multiple Transactions when payment is made in installments. Transactions are the financial ground truth — all revenue figures are derived from Transaction amounts grouped by period and unit.

FieldTypeRequiredNotes
idulidyesPK
order_idulidyesFK → commerce_order
datedateyes
amountdecimalyesIn IDR
payment_channelstringnoBank account used, e.g. MANDIRI, BCA REAL
payment_method_idulidnoFK → finance_payment_method
payment_status_idulidyesFK → finance_payment_status
batch_refstringnoBarsheet value from source
source_filestringnoAudit — name of the source file
source_sheetstringnoAudit — sheet name within the source file

marketing_ — Marketing

marketing_channel_type

The classification of a Marketing Channel. Replaces the inline category string field — channel types are now a proper lookup table, extensible without schema changes. Initial values mirror the previous category field but can be expanded (e.g. Print, Outdoor, Social, Search).

FieldTypeRequiredNotes
idulidyesPK
namestringyese.g. Conventional, Digital
source_termstringnoe.g. Konvensional, Digital Marketing

marketing_channel

A channel through which a Person discovered or was acquired. Channels are seeded from the registry and rarely change. Each channel belongs to a type defined in marketing_channel_type. Examples: KBM, Social Media, Referral, Website, Billboard.

FieldTypeRequiredNotes
idulidyesPK
namestringyese.g. KBM, Social Media, Referral
channel_type_idulidyesFK → marketing_channel_type
source_termstringnoOriginal term in source data, e.g. Sosial Media, Teman

marketing_segment

A named audience segment used to scope marketing agendas and activities. Segments describe the intended target audience in human-readable terms. Structured query criteria may be added in a future iteration.

FieldTypeRequiredNotes
idulidyesPK
namestringyese.g. SMA Students, Working Adults, Parents of Kids Programs
descriptionstringnoFree-form notes describing the target audience

marketing_agenda

A planned marketing initiative or campaign. An Agenda represents intent — what the team plans to do and when. Channels, segments, and target organizations are attached via join tables, allowing one agenda to target multiple audiences and channels simultaneously. Agendas can be scoped to a specific Unit or set at the Entity level.

FieldTypeRequiredNotes
idulidyesPK
entity_idulidyesFK → core_entity
unit_idulidnoFK → core_unit — null means entity-level agenda
titlestringyesDescription of the planned initiative
planned_datedateyes
target_leadsintnoExpected total lead count across all channels
notesstringno

marketing_agenda_channel

Join table linking Agendas to Channels (M2M). One agenda can use multiple channels simultaneously.

FieldTypeRequiredNotes
agenda_idulidyesFK → marketing_agenda
channel_idulidyesFK → marketing_channel

marketing_agenda_segment

Join table linking Agendas to Segments (M2M). One agenda can target multiple audience segments.

FieldTypeRequiredNotes
agenda_idulidyesFK → marketing_agenda
segment_idulidyesFK → marketing_segment

marketing_agenda_organization

Join table linking Agendas to Organizations (M2M). Records which specific schools or institutions are planned to be targeted by an agenda.

FieldTypeRequiredNotes
agenda_idulidyesFK → marketing_agenda
organization_idulidyesFK → db_organization

marketing_agenda_target

Join table linking Agendas to Targets (M2M). One agenda can have multiple targets (e.g. leads, closings, revenue); one target can be shared across multiple agendas.

FieldTypeRequiredNotes
agenda_idulidyesFK → marketing_agenda
target_idulidyesFK → target_item

marketing_activity

The execution record of a marketing effort — what was actually done and what it produced. An Activity may be linked to a planned Agenda or recorded ad-hoc. The closings count is cross-checked against Order channel data by the Format layer. Segments reached and organizations visited are attached via join tables.

FieldTypeRequiredNotes
idulidyesPK
agenda_idulidnoFK → marketing_agenda — nullable for ad-hoc activities
entity_idulidyesFK → core_entity
unit_idulidnoFK → core_unit
channel_idulidyesFK → marketing_channel — one channel per execution
datedateyes
leadsintnodefault 0
follow_upsintnodefault 0
closingsintnodefault 0 — cross-checked against Order channel data by Format layer
notesstringno

marketing_activity_segment

Join table linking Activities to Segments (M2M). Records which audience segments were actually reached during the activity.

FieldTypeRequiredNotes
activity_idulidyesFK → marketing_activity
segment_idulidyesFK → marketing_segment

marketing_activity_organization

Join table linking Activities to Organizations (M2M). Records which specific schools or institutions were actually visited or reached during the activity.

FieldTypeRequiredNotes
activity_idulidyesFK → marketing_activity
organization_idulidyesFK → db_organization

target_ — Target

target_metric

The measurable quantity a Target is set against.

FieldTypeRequiredNotes
idulidyesPK
namestringyesRevenue, Orders, Leads, Follow-ups, Closings
source_termstringno

target_item

A goal set for a specific metric over a specific period. Targets are universal — they can be set at entity, unit, item, or marketing channel level by leaving the corresponding FK fields null. The report layer checks for misalignments between levels independently; targets at different levels are not required to sum to each other.

FieldTypeRequiredNotes
idulidyesPK
entity_idulidyesFK → core_entity — always required
unit_idulidnoFK → core_unit — null means entity-level
item_idulidnoFK → catalog_item — null means unit or entity-level
channel_idulidnoFK → marketing_channel
metric_idulidyesFK → target_metric
period_yearintyese.g. 2026
period_monthintno1–12 — null means annual target
valuedecimalyes

Business Rules

  1. Enrollment requires a Participant. A commerce_order with order type Enrollment must have a participant_id. All other order types may leave it null.

  2. Customer type is stored and computable. customer_type_id on commerce_order is stored at sync time (taken from source data). It can be recomputed by counting all prior orders for the same participant_id across any Unit: none found → New; most recent order within 1 year → Renewal; most recent order over 1 year ago → Alumni.

  3. Targets are independent across levels. A unit-level target and an entity-level target for the same metric and period are separate records. The Format layer reports both and flags misalignments; it does not enforce that they must sum.

  4. Marketing closings are cross-checked, not enforced. The closings count on marketing_activity should equal the count of orders where channel_id matches the activity's channel for the same unit and date range. The Format layer reports discrepancies but does not block data entry.

  5. Revenue is always derived from Transactions. No revenue field is stored on commerce_order. All revenue figures are computed by summing finance_transaction.amount grouped by unit, period, and any other dimension at query time.

  6. Relation is directed. A db_relation record from Person A to Person B with type Guardian means A is guardian of B — not the reverse. The reverse relationship, if needed, requires a separate record.

  7. Catalog price resolution. When resolving the price for an order, first check for a catalog_price record matching the variant_id in the active price list. If not found, fall back to the item_id price in the same list.

  8. Brand-Unit consistency. A catalog_item references both a brand_id and a unit_id. The unit must be a member of the brand (i.e. a catalog_brand_unit record must exist for that brand-unit pair).


Entity Relationship Diagram (Detailed)

Full columns. PKs marked with PK, FKs marked with FK.