Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,18 @@ assignees: ''

## Environment

- **Platform**: Web / Android
- **Platform**: Web / Android / iOS / Backend
- **Workspace mode**: Local Mode / Server Mode / Not sure
- **Browser** (if web):
- **Device/Emulator** (if Android):
- **Simulator/Device** (if iOS):
- **T'Day version**:
- **OS**:

## Data / Sync Context

<!-- If relevant: scheduled todo vs floater, list vs floater list, offline/online state, pending sync, Local Mode, recent server URL/auth changes. -->

## Screenshots / Logs

<!-- Attach screenshots, error messages, or relevant logs. -->
Expand Down
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,18 @@ assignees: ''

<!-- Describe the feature or change you'd like. -->

## Product Surface

<!-- Which surfaces need this? Web, backend/API, shared DTOs, Android, iOS, Local Mode, Server Mode, scheduled tasks, floaters, calendar, completed history, settings, deployment, docs. -->

## Alternatives Considered

<!-- Any alternative solutions or workarounds you've thought about. -->

## Parity / Data Notes

<!-- Note expected Android/iOS parity, data model changes, API changes, sync behavior, or documentation updates. -->

## Additional Context

<!-- Mockups, examples from other apps, or any other context. -->
12 changes: 11 additions & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@

-

## Product / Data Impact

<!-- Note Local Mode, Server Mode, mobile parity, API, shared DTO, backend table, Room, SwiftData, or sync impacts. Write "None" if not applicable. -->

## Type of Change

- [ ] Feature (new functionality)
- [ ] Bug fix (non-breaking fix)
- [ ] Refactor (no behavior change)
- [ ] Chore (deps, CI, docs, tooling)
- [ ] Breaking change (existing behavior altered)
- [ ] Documentation-only

## Pre-Merge Checklist

Expand All @@ -24,9 +29,14 @@
- [ ] No AI tool attribution in commits or PR description — no `Co-authored-by`, `Made-with`, or any trailer/text referencing Cursor, Codex, Copilot, ChatGPT, Claude, etc.
- [ ] Backward compatibility maintained (or migration provided)
- [ ] Flyway migration reviewed (if schema changed)
- [ ] Shared DTOs / Android Room / iOS SwiftData / sync mappers reviewed (if data shape changed)
- [ ] Local Mode behavior reviewed (if mobile behavior changed)
- [ ] Android/iOS parity checked (if mobile UI changed)
- [ ] Relevant docs updated (`README`, product/data/API/architecture/testing/platform docs)
- [ ] Error handling and logging added where needed
- [ ] API changes follow [API Guidelines](docs/API_GUIDELINES.md)
- [ ] API changes follow [API Guidelines](../docs/API_GUIDELINES.md)
- [ ] Android changes tested on emulator or device (if applicable)
- [ ] iOS changes tested on simulator or device (if applicable)

## Testing

Expand Down
38 changes: 33 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
# T'Day Agent Guide

This file is the working agreement for AI agents contributing to T'Day. Read it with `README.md`, `docs/ARCHITECTURE.md`, `docs/CODING_STANDARDS.md`, and `docs/TESTING.md`.
This file is the working agreement for AI agents contributing to T'Day. Read it with `README.md`, `docs/PRODUCT_DIRECTION.md`, `docs/DATA_MODEL.md`, `docs/ARCHITECTURE.md`, `docs/CODING_STANDARDS.md`, `docs/TESTING.md`, and `docs/REPO_HOUSEKEEPING.md`.

## Project Shape

T'Day is a private, self-hosted personal task planner with:

- `tday-web/`: Vite, React, TypeScript, Tailwind, i18next.
- `tday-backend/`: Ktor, Exposed, Flyway, PostgreSQL, JWE sessions.
- `shared/`: Kotlin Multiplatform DTOs, enums, and validators consumed by backend, Android, and iOS.
- `android-compose/`: Native Android app using Kotlin, Jetpack Compose, Hilt, Retrofit, offline cache and sync.
- `ios-swiftUI/`: Native iOS app using SwiftUI, SwiftData, Observation, URLSession, Keychain/cookie handling.
- `shared/`: Kotlin Multiplatform DTOs, enums, validators, and route constants consumed by backend/Android and mirrored by iOS contract models.
- `android-compose/`: Native Android app using Kotlin, Jetpack Compose, Hilt, Retrofit, Room offline cache, reminders, widgets, and sync.
- `ios-swiftUI/`: Native iOS app using SwiftUI, SwiftData, Observation, URLSession, Keychain/cookie handling, reminders, and widget snapshots.

The native mobile apps should feel like one product expressed through two platform-native implementations.

Current product direction:

- Scheduled `Todo` items have due-date, recurrence, reminder, calendar, and scheduled-list semantics.
- `Floater` items are unscheduled Anytime tasks with separate floater lists and completed history.
- Local Mode is a first-class mobile workspace and must not silently upload local-only data to a server workspace.
- Server Mode uses local optimistic writes plus pending mutation replay.
- Documentation is part of the deliverable when behavior, structure, API, data shape, or verification changes.

## How To Work In This Repo

- Start by checking `git status --short --branch`. The worktree may already contain user changes.
Expand All @@ -23,6 +31,7 @@ The native mobile apps should feel like one product expressed through two platfo
- When the user asks for implementation, implement it, verify it, then report clearly.
- When the user asks for a PR, push the active branch and open/update the PR they requested.
- When resolving merge conflicts into an outdated base, prefer the active/latest branch behavior unless the user explicitly says otherwise.
- When the user asks for documentation, inspect the real project state and recent commits before writing broad claims.

## Git And Attribution

Expand All @@ -44,6 +53,7 @@ Before finishing a mobile UI task, ask:
- Do labels, task counts, date rules, empty states, and disabled states match?
- Do navigation rules match, including lower bounds and edge cases?
- Does the interaction feel platform-native on each OS?
- Does Local Mode hide/disable server-only affordances consistently?
- Is one platform now clearly nicer? If yes, bring the other platform up to the same product quality.

Do not blindly copy implementation details across platforms. Copy behavior, interaction rules, information architecture, and visual intent while using native APIs and established local patterns.
Expand All @@ -63,6 +73,7 @@ Core rules:
- Task counts come from pending scheduled items grouped by local start-of-day.
- Day and week task counts cap display at `9+`.
- The task section title stays in the form `Tasks due EEE, MMM d`.
- Floaters do not appear on the calendar unless a future product decision gives them scheduled semantics.

Interaction rules:

Expand Down Expand Up @@ -90,6 +101,7 @@ T'Day is a task app, not a marketing site. Mobile screens should feel quiet, use
- Text must fit in compact mobile layouts without overlap or truncation that hides meaning.
- Empty states should be calm and short.
- Preserve dark mode.
- Root feed behavior should stay aligned: Home and Floater/Anytime are sibling root feeds controlled by `RootFeedDock`, with the create action available from the root controls.

## Design Tokens And Strings

Expand All @@ -102,30 +114,46 @@ T'Day is a task app, not a marketing site. Mobile screens should feel quiet, use

## Architecture Expectations

Across the repo, keep changes shaped around readable boundaries: a file or type should have a clear reason to exist, dependencies should flow from UI to state to services/repositories to storage/network, and helpers should start local before being promoted to shared.

Backend:

- Keep request/response contracts aligned with `shared/` models when possible.
- Services return typed errors and avoid leaking internals.
- Preserve tenant isolation in all data access.
- Keep scheduled-task routes, floater routes, scheduled-list routes, and floater-list routes distinct.
- Routes translate HTTP and validation; services own business decisions; Exposed table/query code stays out of UI-facing layers.

Android:

- Use MVVM with `@HiltViewModel`, `StateFlow`, repositories, and app services.
- Keep mutable state private and expose read-only state.
- Respect offline-first cache/sync behavior.
- Respect Room-backed offline-first cache/sync behavior and Local Mode.
- Use Compose idioms and Material 3.
- ViewModels depend on injected repositories/services, not Retrofit, Room DAOs, or storage details directly.

iOS:

- Use SwiftUI, Observation, SwiftData, and URLSession patterns already present in the app.
- Keep feature code inside `Feature/<Name>/` unless it is truly shared.
- Prefer small local helpers before creating broad abstractions.
- Keep `AppContainer` wiring explicit and update SwiftData/cache mappers with data model changes.
- Views render state and invoke actions; repositories/cache managers own persistence and sync details.

Web:

- Use React Query for server state.
- Use the shared API client, not raw backend `fetch` calls from components.
- Use Tailwind semantic tokens and locale keys.
- Keep feature modules cohesive and move repeated logic into `src/lib/`, `src/hooks/`, or feature-scoped helpers only when that reduces real duplication.

Docs:

- Update `README.md` for project shape and documentation-map changes.
- Update `docs/DATA_MODEL.md` for table, DTO, local cache, and pending mutation changes.
- Update `docs/API_GUIDELINES.md` for route changes.
- Update `docs/ARCHITECTURE.md` for data flow, module, and platform architecture changes.
- Update platform READMEs for Android/iOS setup, storage, sync, or feature-surface changes.

## Verification Commands

Expand Down
73 changes: 67 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ This document covers everything a developer needs to know before writing code, o
## Table of Contents

- [Development Setup](#development-setup)
- [Product Direction](#product-direction)
- [Branch Strategy](#branch-strategy)
- [Commit Messages](#commit-messages)
- [Pull Request Process](#pull-request-process)
- [Documentation Expectations](#documentation-expectations)
- [Coding Conventions](#coding-conventions)
- [Linting and Formatting](#linting-and-formatting)
- [Testing](#testing)
Expand Down Expand Up @@ -39,9 +41,16 @@ bash scripts/install-hooks.sh # install git hooks (required, one-time)

1. Open `android-compose/` in Android Studio.
2. Ensure Android SDK 35 is installed.
3. Set the server URL at first launch to point to your local or remote T'Day instance.
3. Choose Local Mode for offline-only testing, or set the server URL at first launch to point to your local or remote T'Day instance.
4. Run on emulator or physical device.

### iOS (SwiftUI)

1. Open `ios-swiftUI/TdayApp.xcodeproj` in Xcode.
2. Select the `Tday` scheme.
3. Run on an iOS 17+ simulator or physical device.
4. Choose Local Mode for offline-only testing, or connect to a self-hosted server.

### Database

PostgreSQL 15 is required. Use Docker or a local installation:
Expand All @@ -59,6 +68,17 @@ docker compose up -d --build
docker exec -it tday_ollama ollama pull qwen2.5:0.5b
```

## Product Direction

Read [`docs/PRODUCT_DIRECTION.md`](docs/PRODUCT_DIRECTION.md) before changing product behavior. The short version:

- T'Day is a quiet private planner with web, backend, Android, and iOS surfaces.
- Mobile is local-first and cross-platform parity matters.
- Scheduled `Todo` items and unscheduled `Floater` items are separate domain concepts.
- Local Mode is a first-class Android/iOS workspace that does not require a server.
- Server Mode writes optimistically to local cache and replays pending mutations to the backend.
- Documentation should move with behavior, data shape, architecture, and verification changes.

## Branch Strategy

| Branch | Purpose | Deploys to |
Expand Down Expand Up @@ -119,10 +139,12 @@ docs: add architecture decision record for offline sync
2. Make your changes following [coding standards](docs/CODING_STANDARDS.md).
3. Ensure lint passes: `cd tday-web && npm run lint`.
4. Ensure tests pass: `cd tday-web && npm run test` and `./gradlew :tday-backend:test`.
5. Open a PR against `develop` using the [PR template](.github/PULL_REQUEST_TEMPLATE.md).
6. Request review from at least one maintainer.
7. Address all review comments.
8. Squash-merge when approved.
5. For Android changes, run `cd android-compose && ./gradlew :app:compileDebugKotlin` and targeted tests when practical.
6. For iOS changes, run the `Tday` scheme build/test in Xcode or the `xcodebuild` command from [`docs/TESTING.md`](docs/TESTING.md).
7. Open a PR against `develop` using the [PR template](.github/PULL_REQUEST_TEMPLATE.md).
8. Request review from at least one maintainer.
9. Address all review comments.
10. Squash-merge when approved.

**CI enforcement:** PRs to `master` run lint and the full test suite automatically. The Docker image will **not** be built or released unless all tests pass. See [Deployment > Test-Before-Build Policy](docs/DEPLOYMENT.md#test-before-build-policy).

Expand All @@ -131,6 +153,7 @@ docs: add architecture decision record for offline sync
- Aim for < 400 lines changed per PR.
- Split large features into incremental PRs.
- Refactoring PRs should not include behavior changes.
- Cross-platform mobile changes should stay behaviorally paired even when implementation differs.

### Review Checklist (for reviewers)

Expand All @@ -139,13 +162,31 @@ docs: add architecture decision record for offline sync
- [ ] Error handling covers failure paths.
- [ ] New API endpoints follow [API guidelines](docs/API_GUIDELINES.md).
- [ ] Database changes include a Flyway migration and are backward-compatible.
- [ ] Shared DTO, Android Room, iOS SwiftData, and sync mappers are updated if the data shape changed.
- [ ] Tests cover the happy path and at least one error path.
- [ ] No console.log / Log.d left from debugging.

## Documentation Expectations

Documentation is part of the change when a future contributor would otherwise have to rediscover the rule.

| Change | Docs to update |
|--------|----------------|
| Product surface, navigation, Local Mode, or cross-platform UX rule | `README.md`, `docs/PRODUCT_DIRECTION.md`, platform READMEs |
| Backend table, shared DTO, local cache record, mutation kind | `docs/DATA_MODEL.md`, `docs/ARCHITECTURE.md`, `docs/API_GUIDELINES.md` |
| Route or response contract | `docs/API_GUIDELINES.md`, shared models, tests |
| Coding pattern or guardrail | `docs/CODING_STANDARDS.md`, guardrail tests |
| Verification workflow or CI expectation | `docs/TESTING.md`, `.github/PULL_REQUEST_TEMPLATE.md` |
| Deployment, versioning, signing, ingress, telemetry, security | The matching doc under `docs/`, `SECURITY.md`, or platform README |

Use [`docs/REPO_HOUSEKEEPING.md`](docs/REPO_HOUSEKEEPING.md) for generated-file rules, markdown maintenance, and cleanup expectations.

## Coding Conventions

See [`docs/CODING_STANDARDS.md`](docs/CODING_STANDARDS.md) for the full rules. Key highlights:

Across all codebases, prefer readable, narrow units with explicit names and clear dependency direction. UI renders state, ViewModels/controllers coordinate, repositories/services own data work, and transport/storage details stay behind injected collaborators.

### TypeScript (Frontend)

- Strict mode is enabled — no `any` unless absolutely unavoidable.
Expand All @@ -161,6 +202,13 @@ See [`docs/CODING_STANDARDS.md`](docs/CODING_STANDARDS.md) for the full rules. K
- Use `runCatching` for operations that can fail.
- Constants in `companion object` with `UPPER_SNAKE_CASE`.

### Swift (iOS)

- Use SwiftUI, Observation, SwiftData, URLSession, Keychain/cookie handling, and the existing `AppContainer` dependency graph.
- Keep feature code in `ios-swiftUI/Tday/Feature/<Feature>/` and shared app logic in `Core/`.
- Mirror product behavior with Android while keeping platform-native UI, gestures, and system integrations.
- Update SwiftData entities and cache mappers whenever offline state changes.

## Linting and Formatting

### Frontend
Expand Down Expand Up @@ -212,20 +260,33 @@ npm run test # all Vitest suites
- Tests go in `app/src/test/` (unit) and `app/src/androidTest/` (instrumented).
- Test naming: `should <expected behavior> when <condition>`.

### iOS

```bash
xcodebuild test -project ios-swiftUI/TdayApp.xcodeproj -scheme Tday -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.6'
```

- Tests live in `ios-swiftUI/Tests/`.
- Prefer focused tests for repository/cache mapping, sync behavior, and core helpers.
- For UI polish without tests, build the app and do a simulator/device spot check when practical.

## Before Merging Checklist

Every PR must satisfy these before merge:

- [ ] `cd tday-web && npm run lint` passes with no warnings.
- [ ] `cd tday-web && npm run test` passes with no failures (including guardrail tests).
- [ ] `./gradlew :tday-backend:test` passes with no failures.
- [ ] Android build/tests run for Android changes, or the skip reason is documented.
- [ ] iOS build/tests run for iOS changes, or the skip reason is documented.
- [ ] CI pipeline passes (lint + tests are enforced automatically on PRs to `master`).
- [ ] No secrets or credentials in the diff.
- [ ] No AI tool attribution in commits or PR description — no `Co-authored-by`, `Made-with`, or any trailer/text referencing Cursor, Codex, Copilot, ChatGPT, Claude, etc.
- [ ] Backward compatibility maintained (or migration provided).
- [ ] Flyway migration SQL and corresponding Exposed table changes reviewed if schema changed.
- [ ] Shared DTOs, Android Room, iOS SwiftData, and sync mappers reviewed if data shape changed.
- [ ] Error handling and logging added where appropriate.
- [ ] API changes documented in the PR description.
- [ ] Android changes tested on emulator or device.
- [ ] Android/iOS parity checked for mobile user-facing changes.

**Note:** The release pipeline will not build or push a Docker image unless all tests pass. Broken tests block the entire release.
Loading
Loading