docs: add STRUCTURE.md describing targets, layout, and architecture
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
108
STRUCTURE.md
Normal file
108
STRUCTURE.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Project Structure
|
||||
|
||||
KisaniCal (display name **Wenza**) is a personal productivity + fitness iOS app,
|
||||
built with SwiftUI and generated from `project.yml` via [XcodeGen]. It ships an
|
||||
iOS app, a WidgetKit extension, and an optional watchOS companion.
|
||||
|
||||
## Build targets
|
||||
|
||||
Defined in [`project.yml`](project.yml):
|
||||
|
||||
| Target | Type | Platform | Bundle ID |
|
||||
|---|---|---|---|
|
||||
| `KisaniCal` | application | iOS 16+ | `com.kutesir.KisaniCal` |
|
||||
| `KisaniCalWidgets` | app-extension | iOS 18+ | `com.kutesir.KisaniCal.KisaniCalWidgets` |
|
||||
| `WenzaWatch` | application | watchOS 10+ | `com.kutesir.KisaniCal.watchkitapp` |
|
||||
| `KisaniCalTests` | unit-test | iOS 16+ | — |
|
||||
|
||||
`WenzaWatch` is built/embedded only when the watchOS platform is installed
|
||||
(see the commented `embed` note in `project.yml`).
|
||||
|
||||
## Directory layout
|
||||
|
||||
```
|
||||
KisaniCal/ repo root (Gitea: kutesir/KisaniCal)
|
||||
│
|
||||
├── project.yml XcodeGen spec — source of truth for the .xcodeproj
|
||||
├── KisaniCal.xcodeproj generated (do not hand-edit)
|
||||
│
|
||||
├── KisaniCal/ 📱 main iOS app target
|
||||
│ ├── KisaniCalApp.swift @main entry point
|
||||
│ ├── ContentView.swift root view / tab shell
|
||||
│ ├── KisaniCal.entitlements
|
||||
│ ├── LaunchScreen.storyboard
|
||||
│ ├── Views/ SwiftUI screens (13)
|
||||
│ │ ├── TodayView, CalendarView, MatrixView tasks
|
||||
│ │ ├── WorkoutView, AddExerciseSheet fitness
|
||||
│ │ ├── AuthView, OnboardingView, ProfileSetupView, SplashView
|
||||
│ │ ├── SettingsView, TutorialView
|
||||
│ │ └── TaskContextMenu, TodayMenuFeatures
|
||||
│ ├── Managers/ stateful service singletons (10)
|
||||
│ │ ├── AuthManager, CloudSyncManager auth + iCloud KVS
|
||||
│ │ ├── HealthKitManager, SpeechRecognizer system frameworks
|
||||
│ │ ├── NotificationManager, LiveActivityManager, ShortcutHandler
|
||||
│ │ ├── TutorialManager
|
||||
│ │ └── AppGroup, TaskActivityAttributes shared with widgets
|
||||
│ ├── Models/ TaskItem, ExerciseModels, CalendarGrid
|
||||
│ ├── Components/ SharedComponents, FloatingTabState
|
||||
│ └── Theme/ DesignTokens
|
||||
│
|
||||
├── KisaniCalWidgets/ 🧩 WidgetKit extension (iOS 18+)
|
||||
│ ├── KisaniCalWidgets.swift, MyTasksWidget, EventCountdownWidget
|
||||
│ ├── TaskLiveActivity, WidgetViews, WidgetData
|
||||
│ └── Info.plist, .entitlements
|
||||
│
|
||||
├── WenzaWatch/ ⌚️ watchOS companion (build-optional)
|
||||
│ └── WenzaWatchApp.swift, Info.plist, .entitlements
|
||||
│
|
||||
├── KisaniCalTests/ 🧪 unit tests (the CI test target)
|
||||
│ └── CalendarGridTests, RecurrenceTests, NLRecurrenceParseTests
|
||||
│
|
||||
├── .gitea/workflows/ 🔧 CI/CD (Gitea Actions)
|
||||
│ ├── ci.yml build + test on PRs into main/develop
|
||||
│ └── release.yml archive + export IPA on push to main
|
||||
│
|
||||
├── scripts/gitea-setup.sh Gitea branch-protection / default-branch setup
|
||||
├── ExportOptions.plist IPA export template
|
||||
│
|
||||
├── CONTRIBUTING.md branch workflow + PR gate rules
|
||||
├── PRODUCT.md product brief, users, design principles
|
||||
├── SERVICES.md backing services / infra notes
|
||||
├── ISSUES.md running issue log (KC-## ids)
|
||||
└── Sanctum-Auto-FailOver-Uptime-Kuma.md
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
A flat SwiftUI **MVVM-lite** layout, organized by role rather than by feature:
|
||||
|
||||
- **Views** — SwiftUI screens, one file per screen.
|
||||
- **Managers** — `ObservableObject` service singletons holding cross-cutting
|
||||
state (auth, iCloud sync, HealthKit, notifications, speech, Live Activities).
|
||||
- **Models** — plain data types (`TaskItem`, exercise/workout models, calendar
|
||||
grid math).
|
||||
- **Components / Theme** — shared UI and design tokens.
|
||||
|
||||
Three product domains coexist in one app:
|
||||
|
||||
1. **Tasks** — Today list, Calendar, Eisenhower Matrix; natural-language quick
|
||||
add (with voice via `SpeechRecognizer`).
|
||||
2. **Fitness** — workout logging with weighted/bodyweight sets; reads/writes
|
||||
Health via `HealthKitManager`.
|
||||
3. **Calendar / events** — surfaced on the dashboard, in **widgets**, and as
|
||||
**Live Activities**.
|
||||
|
||||
### Cross-target code sharing
|
||||
|
||||
`KisaniCal/Managers/AppGroup.swift` and `TaskActivityAttributes.swift` are
|
||||
compiled into **both** the app and the widget extension (see the widget target's
|
||||
`sources` in `project.yml`), so task/activity data is shared through the App
|
||||
Group container.
|
||||
|
||||
### Persistence & sync
|
||||
|
||||
State is persisted locally and mirrored to **iCloud key-value store** via
|
||||
`CloudSyncManager`. Restore-on-launch rehydrates data after reinstall/update
|
||||
(see ISSUES.md KC-39 for the save/restore symmetry the sync layer must keep).
|
||||
|
||||
[XcodeGen]: https://github.com/yonaskolb/XcodeGen
|
||||
Reference in New Issue
Block a user