Контент-коллекции (Этап 7)
Коллекции «Этапа 7» описывают публичный контент студии: блог, команду, информацию о компании, процесс работы и контакты. Данные читает Client из мобилки и Public (анонимно — для будущего сайта). Пишут администраторы и Content Editor’ы.
Коллекции
Заголовок раздела «Коллекции»| Коллекция | Singleton | Назначение | Экраны мобилки |
|---|---|---|---|
blog_posts | нет | новости компании | 24 |
employees | нет | команда студии | 07 |
company_info | да | текст + галерея о компании | 28 |
how_we_work | да | процесс работы (wrapper) | 23 |
how_we_work_steps | нет | шаги процесса (O2M от how_we_work) | 23 |
company_contacts | да | контактные данные | 13 |
company_info_files | нет, hidden | junction для M2M company_info.images ↔ directus_files | — |
employees
Заголовок раздела «employees»Добавлена в рамках Этапа 7 (её не было на старте MVP). TypeScript-тип — см. dimetra-claude/docs/DATA_MODEL.md → Employee.
| Поле | Тип | Описание |
|---|---|---|
id | uuid | PK |
full_name | string | ФИО |
role | string | Должность |
bio | text | Краткая биография |
photo_id | FK → directus_files | Портретное фото |
order | integer | Сортировка (меньше — выше) |
status | enum | active / archived (archive_field коллекции) |
created_at | timestamp | date-created |
Singleton’ы и связанные коллекции
Заголовок раздела «Singleton’ы и связанные коллекции»company_info
Заголовок раздела «company_info»| Поле | Тип | Описание |
|---|---|---|
description | text (richtext) | Описание компании |
images | M2M → directus_files (alias, через company_info_files) | Галерея фото |
how_we_work + how_we_work_steps
Заголовок раздела «how_we_work + how_we_work_steps»how_we_work (singleton) └─ steps (O2M → how_we_work_steps) id, how_we_work_id (FK), title, description, image_id (FK → directus_files), orderКлиент читает how_we_work с deep fields steps.* и сортирует их по order.
company_contacts
Заголовок раздела «company_contacts»Поля: phone, email, address, telegram, instagram, website — всё string, один singleton.
Пример чтения (мобилка)
Заголовок раздела «Пример чтения (мобилка)»import { readItems, readSingleton } from '@directus/sdk';
// Экран 07 — Сотрудникиawait client.request(readItems('employees', { fields: ['id', 'full_name', 'role', 'bio', 'photo_id', 'order'], filter: { status: { _eq: 'active' } }, sort: ['order'],}));
// Экран 24 — Новостиawait client.request(readItems('blog_posts', { fields: ['id', 'title', 'slug', 'featured_image_id', 'published_at', 'content'], filter: { status: { _eq: 'published' } }, sort: ['-published_at'],}));
// Экран 28 — О компании (singleton + M2M галерея)await client.request(readSingleton('company_info', { fields: ['id', 'description', 'images.directus_files_id'],}));
// Экран 23 — Как мы работаем (singleton + O2M шаги)await client.request(readSingleton('how_we_work', { fields: [ 'id', 'steps.id', 'steps.title', 'steps.description', 'steps.image_id', 'steps.order', ], deep: { steps: { _sort: ['order'] } },}));
// Экран 13 — Контактыawait client.request(readSingleton('company_contacts', { fields: ['phone', 'email', 'address', 'telegram', 'instagram', 'website'],}));Не используйте fields: ['*'] — на company_info это сломается о junction alias (см. docs/directus-api-pitfalls.md → phantom-o2m-aliases-on-fields-star).
Permissions
Заголовок раздела «Permissions»Матрица применена скриптом backend/scripts/setup-phase-7.ts, включена в snapshot.
| Коллекция | Client (мобилка) | Public (анонимно) | Content Editor | Administrator |
|---|---|---|---|---|
blog_posts | read | read | CRUD | all |
employees | read | read | CRUD | all |
company_info | read | read | update | all |
how_we_work | read | read | update | all |
how_we_work_steps | read | read | CRUD | all |
company_contacts | read | read | update | all |
directus_files | create, read | read | read | all |
Project Manager и Bot Service по умолчанию к этим коллекциям доступа не имеют — они работают только с проектами/чатами/платежами.
Seeding и регенерация (для администратора БД)
Заголовок раздела «Seeding и регенерация (для администратора БД)»Два идемпотентных скрипта в backend/scripts/:
setup-phase-7.ts— коллекцияemployees, aliascompany_info.images, permissionsseed-phase-7.ts— демо-контент (singleton’ы, 5 шагов, 3 сотрудника, 3 поста)
Запуск:
cd backend
# структураDIRECTUS_URL=http://localhost:8055 DIRECTUS_TOKEN=<admin-token> \ npx tsx scripts/setup-phase-7.ts
# демо-контентDIRECTUS_URL=http://localhost:8055 DIRECTUS_TOKEN=<admin-token> \ npx tsx scripts/seed-phase-7.tsОба можно перезапускать — существующие записи пропускаются по ключу (slug для постов, full_name для сотрудников, title для шагов).
Guard «Алматы → Караганда»
Заголовок раздела «Guard «Алматы → Караганда»»seed-phase-7.ts перезаписывает singleton’ы company_info и company_contacts только если текущее содержимое выглядит как дефолтный seed «Алматы» (регулярка на /Алматы|727/i) или пустое. Ручные правки от Content Editor’а не затираются — guard проверяет содержимое перед PATCH.
Регенерация snapshot и registry
Заголовок раздела «Регенерация snapshot и registry»После изменений схемы:
cd backend && npm run schema:snapshot # → backend/snapshots/schema.yamlcd .. && DIRECTUS_ADMIN_TOKEN=<t> DIRECTUS_URL=http://localhost:8055 \ npx zx .claude/skills/directus-api/scripts/dump-collections.mjs # → docs/directus-api-registry.mdСвязанные документы
Заголовок раздела «Связанные документы»- Полная модель данных с TypeScript-типами:
dimetra-claude/docs/DATA_MODEL.md - Общая страница по Directus: Directus Backend
- Грабли при работе с Directus API:
docs/directus-api-pitfalls.md - Guide для Content Editor’а: Контент сайта