Domain · Architecture

Arete — Architecture

Arete provides a comprehensive personal development platform across 12 Nx libraries and 3 applications (a Fastify REST API, a React/Vite web dashboard, and a React Native mobile app).

9sections8 minread

On this page

Personal development and life mastery domain. Named after the Ancient Greek concept of excellence, virtue, and living up to one's full potential.


Arete is the platform's comprehensive self-improvement engine. A user who wants to build better habits, set structured goals, maintain a reflective journal, manage their time intentionally, clarify their life purpose, or track their overall wellness all finds their home here. The domain is named after the Ancient Greek concept of aretê — living up to one's highest potential — and its theoretical underpinnings draw directly from the evidence-based frameworks that concept inspired in the behavioral sciences: Covey's 7 Habits, Clear's Atomic Habits, Allen's GTD, Newport's deep work methodology, and positive psychology models like PERMA and SWLS.

Architecturally, Arete is one of the largest domains in the monorepo. It spans 12 Nx libraries and 3 applications, and its foundation library (@arete/core) alone defines 56 Zod validation schemas, 61 PostgreSQL tables with ~40 enum types, a database-level streak trigger, full-text search indexes, and nine aggregation functions. This reflects the domain's breadth: personal development is not a single problem but ten overlapping ones, each with its own data model and behavioral science basis.


1. Domain Summary#

Arete provides a comprehensive personal development platform across 12 Nx libraries and 3 applications (a Fastify REST API, a React/Vite web dashboard, and a React Native mobile app). Its theoretical foundation is Stephen Covey's 7 Habits of Highly Effective People, supplemented by James Clear's Atomic Habits, David Allen's GTD, Cal Newport's deep work methodology, and positive psychology frameworks (PERMA, SWLS, CBT).

The domain is uniquely data-heavy: @arete/core alone defines 56 Zod validation schemas, 61 PostgreSQL tables with ~40 enum types, an automatic streak trigger, full-text search indexes, and nine aggregation functions — all in a single foundation library. A second schema family — the "V1" contracts in @oshun/contracts/arete — backs thirteen arete_v1_* tables for the humane-streak / friction-aware coaching model.

Note on libs/arete/database/: A libs/arete/database/ directory exists containing only prisma/schema.prisma and a generated prisma/generated/ SQL file. This directory is not a registered Nx library — it has no package.json or project.json. The authoritative database schema for the Arete domain is the Drizzle ORM schema in @arete/core (src/db-schema.ts), which defines the 61-table schema described throughout this document. The libs/arete/database/prisma/ directory is a supplementary Prisma configuration and does not replace or duplicate the core Drizzle schema.


2. Component Topology#

The twelve libraries are organized into five conceptual layers, each building on the one below. @arete/core is the single shared foundation: every other library depends on it (declared as a peerDependency) and on nothing else in the domain. The feature libraries are deliberately flat siblings — they cannot import each other, so cross-feature integration is the responsibility of the application layer.

text
                       @arete/core
                (schemas, DB schema, seeds)
                /    |    |    |    \
               /     |    |    |     \
 @arete/habits  @arete/goals  @arete/journal  @arete/time  @arete/vision
 @arete/balance  @arete/seven-habits  @arete/affirmations
               \     |    |    /
                \    |    |   /
          @arete/gamification
                    |
          @arete/ai-coach

  @arete/api-client   (standalone generated client; no @arete/core dep)

  apps/arete/api      Fastify REST API   — consumes core, habits, ai-coach
  apps/arete/web      React + Vite       — consumes habits
  apps/arete/mobile   React Native       — consumes the API over HTTP

The two "top-level" libraries, @arete/gamification and @arete/ai-coach, sit above the feature layer conceptually because they aggregate data across all feature areas. In practice, though, they still peer only on @arete/core — cross-feature aggregation happens by querying the database directly rather than importing sibling libraries.


3. Layer Architecture#

Layer 1 — Foundation: @arete/core#

The core library is unusually feature-rich for a foundation. It provides:

56 Zod schemas covering the legacy domain model (schemas.ts). Each schema exports its inferred TypeScript type, so consumers get both runtime validation and compile-time types from a single source of truth. The newer "V1" contract schemas live separately in @oshun/contracts/arete, which @arete/core depends on.

61 Drizzle ORM tables (ALL_ARETE_TABLES) with full relations, foreign keys with cascading deletes, JSONB columns for flexible data storage, and comprehensive indexing. Of these, 48 are legacy tables and 13 are contract-backed arete_v1_* tables.

PostgreSQL automation:

  • STREAK_CALCULATION_TRIGGER_SQL — trigger that fires on arete_habit_completions INSERT, recalculates streak length, and handles forgiveness-day logic automatically in the database
  • STATISTICS_AGGREGATION_SQL — nine aggregation functions for efficient user statistics (total completions, average mood, goal completion rates, etc.)
  • JOURNAL_FULLTEXT_INDEX_SQL — GIN full-text search indexes on journal content

Dependencies: @oshun/contracts, drizzle-orm, zod

Layer 2 — Feature Libraries (8 libraries)#

Each feature library implements a distinct personal development domain. They depend only on @arete/core as a peer dependency and do not depend on each other. Integration between features happens at the application layer.

Library Framework basis Modules
@arete/habits Atomic Habits, Tiny Habits 13
@arete/goals SMART, OKR, WOOP, 12 Week Year 8
@arete/journal Morning Pages, Five-Minute Journal, CBT 9
@arete/time GTD, Eisenhower Matrix, Pomodoro, Deep Work 9
@arete/vision Ikigai, Golden Circle, legacy planning 6
@arete/balance Wheel of Life, PERMA, SWLS 7
@arete/seven-habits Covey's 7 Habits + Emotional Bank Account 8
@arete/affirmations 2

@arete/habits includes three V1-contract modules beyond the eight legacy habit-science modules: recovery, friction, and interventions. It also declares subpath exports (./streaks, ./recovery, ./friction, ./interventions).

Layer 3 — Cross-Cutting: @arete/gamification#

Gamification sits above the feature layer because it aggregates across all feature libraries. Points are awarded for habit completions, goal milestones, journal entries, and time blocks. Badges span multiple life areas. Leaderboards compare overall progress, not just individual habits.

8 modules: points, badges, levels, leaderboards, accountability, contracts, challenges, and rewards.

Layer 4 — Intelligence: @arete/ai-coach#

The AI coach is the top-level consumer of all domain data. It synthesizes habit patterns, goal progress, journal sentiment, energy data, and time use to provide coherent coaching. It also performs NLP analytics across journal content.

9 modules: coaching, recommendations, patterns, weekly-review, coaching-summary-card, continuity-card, cross-domain, NLP analytics, and notifications.

Layer 5 — Applications#

Three applications consume the libraries. @arete/api (apps/arete/api) is a Fastify REST API that depends on @arete/core, @arete/habits, and @arete/ai-coach; it owns persistence (pg + Drizzle), JWT auth, Redis, and the arete_v1_* friction/intervention endpoints. @arete/web (apps/arete/web) is a React + Vite dashboard; @arete/mobile (apps/arete/mobile) is a React Native client. @arete/api-client is a standalone generated HTTP client used by the web and mobile apps and is typed against @oshun/contracts/arete.


4. Dependency Graph#

All twelve libraries are flat siblings at the package level. The dependency graph below shows which layers consume which. @arete/api-client is fully standalone — it depends on neither @arete/core nor any feature library, relying solely on @oshun/contracts/arete for its types.

text
@oshun/contracts ──> @arete/core (drizzle-orm, zod)
                          |
  +-- @arete/habits       (peer: core)
  +-- @arete/goals        (peer: core)
  +-- @arete/journal      (peer: core)
  +-- @arete/time         (peer: core)
  +-- @arete/vision       (peer: core)
  +-- @arete/balance      (peer: core)
  +-- @arete/seven-habits (peer: core)
  +-- @arete/affirmations (peer: core)
  |
  +-- @arete/gamification (peer: core)
  |
  +-- @arete/ai-coach     (peer: core)

@arete/api-client  (no @arete/core dep; typed via @oshun/contracts/arete)

apps/arete/api  ──> @arete/core, @arete/habits, @arete/ai-coach, @oshun/* libs
apps/arete/web  ──> @arete/habits

5. Design Patterns#

Zod-First Typing#

Unlike Hestia (pure TypeScript) or Demeter (Zod in core), Arete uses Zod throughout as the primary type source. Every entity has a Zod schema as its canonical definition. TypeScript types are inferred from schemas, which means consumers get both runtime validation and compile-time types from a single source without duplication:

typescript
const HabitSchema = z.object({ ... });
type Habit = z.infer<typeof HabitSchema>;

This provides runtime validation at all input boundaries with zero type duplication. The 56 legacy schemas in @arete/core plus the V1 contract schemas in @oshun/contracts/arete cover the full domain model and all inter-entity relationships.

Database-Level Business Logic#

Streak calculation and statistics aggregation are pushed into PostgreSQL as triggers and functions rather than implemented in TypeScript. This ensures:

  • Atomicity: streak updates happen in the same transaction as completions
  • Consistency: streaks cannot get out of sync regardless of which client writes
  • Performance: aggregations are computed in the database rather than by pulling all records to TypeScript

Multi-Framework Goal Architecture#

The goals library implements five distinct goal frameworks (basic, SMART, OKR, WOOP, 12 Week Year) as separate modules rather than a single monolithic goal type. This aligns with how users actually think about goals — they may use SMART criteria for some goals and OKR cadences for work objectives.

Evidence-Based Habit Science#

The habits library is organized around the specific psychological models it implements — not generic CRUD. The four-laws module, habit-loop module, and identity module each have separate implementations because they represent distinct behavioral psychology frameworks with different data requirements and user workflows.


6. Module Structure#

Each feature library follows a consistent flat internal structure: every module is a single .ts file directly under src/, paired with a colocated .spec.ts, and re-exported from src/index.ts. V1-contract modules add an src/__tests__/ directory for contract specs.

text
libs/arete/<library>/
├── src/
│   ├── index.ts           # Public API barrel — re-exports every module
│   ├── <module-1>.ts
│   ├── <module-1>.spec.ts
│   ├── <module-2>.ts
│   ├── <module-2>.spec.ts
│   └── __tests__/         # (some libraries) contract specs
├── package.json
├── project.json
├── tsconfig.json
├── tsconfig.lib.json
├── tsconfig.spec.json
└── vitest.config.ts

7. Technology Stack#

The table below summarizes the technology choices per component. The Zod-first approach means validation and type safety share the same source, and the choice of Drizzle ORM (rather than a heavier framework) keeps the schema colocated with TypeScript code.

Component Technology
Language TypeScript (ESM)
Validation Zod (56 schemas in @arete/core; V1 contracts in @oshun/contracts)
ORM Drizzle ORM (drizzle-orm ^0.38.0)
Database PostgreSQL with a trigger, aggregation functions, and GIN indexes
API Fastify (apps/arete/api) with JWT, Redis, Swagger, nodemailer
Web React + Vite, React Router, TanStack Query, Zustand, Tailwind
Mobile React Native 0.73, React Navigation, TanStack Query, Zustand
Build @nx/js:tsc (libraries); nx:run-commandstsc (API)
Testing Vitest (libraries, API, web); Jest (mobile)

8. Project Configuration#

All Arete libraries are tagged uniformly to support Nx target filters. The API application carries a separate layer:service tag because it is a deployed service rather than a shared library.

  • Library project tags: ["scope:arete", "layer:domain", "type:lib"]
  • API project tags: ["scope:arete", "type:app", "layer:service"]
  • Module format: ESM ("type": "module")
  • Library build executor: @nx/js:tsc; library test executor: @nx/vite:test
  • @arete/api builds/tests/runs via the nx:run-commands executor

Common Build Commands#

bash
# Run tests for a single library
pnpm nx test @arete/core
pnpm nx test @arete/habits

# Build all Arete libraries
pnpm nx run-many --target=build --projects=tag:scope:arete

# Run all domain tests
pnpm nx run-many --target=test --projects=tag:scope:arete

# Lint a library
pnpm nx lint @arete/journal

Arete owns personal development and life mastery. Adjacent domains serve complementary purposes but maintain separate codebases with narrow, explicit coupling points:

Domain Relationship
Tara Meditation sessions feed into @arete/balance wellness tracking; @arete/habits habit loop complements daily meditation practice
Kuanyin Compassion ethics frameworks align with Covey's habit 4–6 (win-win, seek to understand, synergize)
Psyche Psychological self-reflection tools in Psyche complement @arete/journal and @arete/balance
Demeter Garden journaling and seasonal living align with Arete's wellness and balance modules

Only the Tara relationship is expressed in code: @arete/habits/recovery exports DEFAULT_TARA_RECOVERY_PRACTICE_REF, and the V1 friction-signal source enum names veritas, metis, tara, and nyx as valid signal sources. The Kuanyin, Psyche, and Demeter rows are conceptual alignments, not code couplings.