Create AGENTS.md
This commit is contained in:
1 parent
ea6abfc139
commit
e73d4dd5e4
1 file changed
+177
@@ -0,0 +1,177 @@
|
||||
# AGENTS.md — BalanceWatch
|
||||
|
||||
Этот файл — точка входа для AI-агентов и разработчиков. Прочитай его
|
||||
целиком перед любым изменением в репозитории.
|
||||
|
||||
## Что это за проект
|
||||
|
||||
**BalanceWatch** — самостоятельное (watch-only) приложение для учёта
|
||||
личных финансов под **watchOS 10+**. Это клиент экосистемы Balance:
|
||||
те же сущности и тот же протокол синхронизации используют iOS/macOS-,
|
||||
Android- и web-клиенты, а синхронизируются все они через self-hosted
|
||||
сервер BalanceServer.
|
||||
|
||||
Проект выделен из монорепозитория Balance: туда входили таргет
|
||||
`BalanceWatch` и общий код, который этот таргет компилировал. Здесь
|
||||
этот код живёт как **копия** (см. раздел «Общий контракт»).
|
||||
|
||||
- UI: SwiftUI, только системные компоненты.
|
||||
- Хранилище: SwiftData, только локально (`cloudKitDatabase: .none`).
|
||||
- Синхронизация: HTTP(S) к BalanceServer, сессия хранится в Keychain.
|
||||
- Внешних зависимостей (SPM/CocoaPods) нет — не добавляй их без явной
|
||||
необходимости.
|
||||
|
||||
## Структура
|
||||
|
||||
```text
|
||||
BalanceWatch/
|
||||
├── AGENTS.md
|
||||
├── README.md
|
||||
├── .github/workflows/build.yml # CI: сборка для симулятора и устройства
|
||||
├── BalanceWatch.xcodeproj/ # один таргет и одна схема — BalanceWatch
|
||||
└── BalanceWatch/
|
||||
├── App/
|
||||
│ ├── BalanceWatchApp.swift # @main, ModelContainer, тема
|
||||
│ ├── WatchRootView.swift # главный экран: баланс, месяц, навигация
|
||||
│ ├── WatchAddTransactionView.swift # добавление операции
|
||||
│ └── WatchFeatures.swift # аналитика, операции, бюджеты,
|
||||
│ # категории, корректировка баланса, настройки
|
||||
├── Models/ # SwiftData-модели и системные категории
|
||||
├── Shared/ # BalanceModelContainer, AppTheme,
|
||||
│ # CategoryDesignOptions, ServerSync (ServerAccountStore)
|
||||
├── Utilities/ # FinanceCalculations, форматирование валют и дат
|
||||
├── Views/Components/CategoryIconView.swift
|
||||
└── Assets.xcassets
|
||||
```
|
||||
|
||||
### Xcode-проект
|
||||
|
||||
`project.pbxproj` использует **папки, синхронизируемые с файловой
|
||||
системой** (`PBXFileSystemSynchronizedRootGroup`, objectVersion 77,
|
||||
нужен Xcode 16+). Любой файл, положенный в `BalanceWatch/`, сам
|
||||
попадает в таргет:
|
||||
|
||||
- чтобы добавить файл, просто создай его в нужной папке, `project.pbxproj`
|
||||
трогать не нужно;
|
||||
- `project.pbxproj` редактируй только ради build settings;
|
||||
- не клади в `BalanceWatch/` файлы, которые не должны попасть в
|
||||
бандл (скрипты, документацию, тестовые данные).
|
||||
|
||||
Ключевые build settings: `SDKROOT = watchos`, `WATCHOS_DEPLOYMENT_TARGET = 10.0`,
|
||||
`INFOPLIST_KEY_WKWatchOnly = YES`, `GENERATE_INFOPLIST_FILE = YES` (своего
|
||||
Info.plist нет — ключи задаются через `INFOPLIST_KEY_*`), bundle id
|
||||
`com.tolamironcenko.Balance.watchkitapp`, `SWIFT_VERSION = 5.0`.
|
||||
|
||||
## Правила разработки
|
||||
|
||||
### 1. Где что менять
|
||||
|
||||
| Что | Где |
|
||||
| --- | --- |
|
||||
| Экраны часов | `App/` |
|
||||
| Модель данных | `Models/` + `Shared/BalanceModelContainer.swift` |
|
||||
| Финансовые правила | `Utilities/FinanceCalculations.swift` |
|
||||
| Авторизация и синхронизация | `Shared/ServerSync.swift` |
|
||||
| Переиспользуемые view | `Views/Components/` |
|
||||
|
||||
Не дублируй доменную логику во view: расчёты — в `FinanceCalculations`,
|
||||
сеть — в `ServerAccountStore`.
|
||||
|
||||
### 2. SwiftData
|
||||
|
||||
Схема зарегистрирована в `BalanceModelContainer.schema`:
|
||||
`FinanceTransaction`, `MonthlyBudget`, `CustomCategory`, `SyncTombstone`.
|
||||
|
||||
- У пользователей уже есть локальные базы. Не удаляй и не переименовывай
|
||||
persisted-поля без стратегии миграции; новые поля делай со значением
|
||||
по умолчанию или опциональными.
|
||||
- Если основное хранилище не открылось, `make()` откатывается на
|
||||
in-memory контейнер `BalanceRecovery`. Не убирай этот fallback.
|
||||
- CloudKit не используется и не должен включаться: единственный
|
||||
источник синхронизации — BalanceServer.
|
||||
|
||||
### 3. Изменение и удаление записей
|
||||
|
||||
- Любое изменение синхронизируемой сущности обязано обновлять
|
||||
`syncUpdatedAt`, иначе изменение не уйдёт на сервер.
|
||||
- Удаляй синхронизируемые сущности через
|
||||
`modelContext.deleteForSync(...)`, а не через `modelContext.delete(...)`:
|
||||
первый вариант пишет tombstone в `SyncDeletionStore`, и удаление
|
||||
доходит до других устройств.
|
||||
- Операции и бюджеты хранят snapshot категории (имя, иконка, emoji,
|
||||
цвет). При переименовании пользовательской категории связанные
|
||||
операции и бюджеты нужно обновить — сохраняй это поведение.
|
||||
|
||||
### 4. Финансовые правила
|
||||
|
||||
Центральные правила — в `FinanceCalculations`:
|
||||
|
||||
- общий баланс = доходы − расходы;
|
||||
- операции с `isBalanceAdjustment == true` входят в общий баланс, но
|
||||
**не** входят в периодическую аналитику (месяц/3 мес./12 мес.);
|
||||
- расходы группируются по `categoryName`.
|
||||
|
||||
Эти правила **одинаковы во всех клиентах Balance** (Apple, Android, web).
|
||||
Не меняй их только здесь.
|
||||
|
||||
### 5. Синхронизация (общий контракт)
|
||||
|
||||
`ServerAccountStore.shared` — единственная точка входа для авторизации и
|
||||
синхронизации (`register`, `login`, `logout`, `sync`). Эндпоинты — `v1/...`
|
||||
на BalanceServer; sync устроен как push изменений после последнего push
|
||||
(транзакции → категории → бюджеты → tombstones), затем pull по `cursor`
|
||||
пачками (`syncBatchSize`, `hasMore`).
|
||||
|
||||
- Формат JSON (`SyncChange`, `SyncRequest`, `SyncResponse`, payload'ы
|
||||
сущностей), семантика cursor/sequence и auth-заголовки — **общий
|
||||
контракт со всеми клиентами и сервером**. Изменение здесь без
|
||||
изменения сервера и остальных клиентов сломает синхронизацию.
|
||||
- При смене URL сервера сессия очищается, cursor/push-state
|
||||
сбрасываются, пользователь логинится заново (`saveServer`). Сохраняй
|
||||
это поведение.
|
||||
|
||||
### 6. Безопасность
|
||||
|
||||
- Пароли не сохраняются нигде. Access/refresh токены — только в Keychain
|
||||
(`KeychainStore`), никогда не в `UserDefaults`, SwiftData или файлах.
|
||||
- Для удалённого сервера — только HTTPS. HTTP разрешён только для
|
||||
`localhost`, `127.0.0.1`, `::1`.
|
||||
- Не логируй пароли, токены и заголовок `Authorization`.
|
||||
- Не коммить секреты, production-URL и credentials.
|
||||
|
||||
### 7. UI на часах
|
||||
|
||||
- Предпочитай `NavigationStack`, `List`, `Form`, короткие списки и
|
||||
компактные действия; крупный текст с `minimumScaleFactor`.
|
||||
- Строки интерфейса — на русском (`developmentRegion = ru`).
|
||||
- Акцентный цвет — `.indigo`; тема берётся из `@AppStorage("appTheme")`
|
||||
через `AppTheme`. Валюта — `@AppStorage("currencyCode")`.
|
||||
- Ключи `@AppStorage`/`UserDefaults` не переименовывай: это сломает
|
||||
настройки у существующих пользователей.
|
||||
|
||||
## Сборка и проверка
|
||||
|
||||
```bash
|
||||
xcodebuild -project BalanceWatch.xcodeproj -scheme BalanceWatch \
|
||||
-destination 'generic/platform=watchOS Simulator' \
|
||||
CODE_SIGNING_ALLOWED=NO build
|
||||
```
|
||||
|
||||
CI (`.github/workflows/build.yml`) собирает проект на `macos-15` для
|
||||
симулятора и для устройства без подписи. Перед PR сборка должна быть
|
||||
зелёной в обоих вариантах.
|
||||
|
||||
Тестового таргета пока нет. Если добавляешь тесты, не завязывай их на
|
||||
текущую дату и локаль — явно фиксируй `Calendar`, `Date` и formatter'ы.
|
||||
Добавив тестовый таргет, добавь и шаг `test` в CI.
|
||||
|
||||
## Чек-лист перед PR
|
||||
|
||||
- [ ] Изменение лежит в правильном слое (`App/`, `Models/`, `Shared/`, `Utilities/`).
|
||||
- [ ] Persisted-поля SwiftData не сломаны, миграция продумана.
|
||||
- [ ] Изменённые синхронизируемые сущности обновляют `syncUpdatedAt`.
|
||||
- [ ] Удаления идут через `deleteForSync`.
|
||||
- [ ] Финансовые правила и sync-контракт не разошлись с остальными клиентами Balance.
|
||||
- [ ] Секреты и токены не попали в репозиторий и логи.
|
||||
- [ ] CI собирает проект для симулятора и для устройства.
|
||||
- [ ] README/AGENTS.md обновлены, если поменялась структура или сборка.
|
||||
Reference in new issue
Block a user