Companion web app for the original E'Magios Core tabletop RPG: character editor, world compendium, and a global dice-roller widget. A diploma project built on React + Feature-Sliced Design.
| Frontend | |
| Backend & data | |
| Hosting | |
| Content pipeline | |
| Tooling | |
| Architecture |
E'Magios Core is an original tabletop RPG. This repository is its digital layer: a player-facing web app built on React + Feature-Sliced Design, paired with an engineering pipeline for publishing world content. It was built as a final qualification (diploma) project.
What this project demonstrates: Feature-Sliced Design at real scale, a content-as-data pipeline with audit and versioning, a role-based access model on top of Firestore, an offline cache in IndexedDB, and a zero-cost deploy guarded by a CI quality gate.
| Feature | Description |
|---|---|
| Character editor | Full-featured character sheet with calculations, equipment, and skills |
| Compendium | World database: spells, creatures, items, schools of magic — with cross-references |
| Dice roller | Global dice widget with roll history and settings |
| Content workflow | Status-based publication model with audit and versioning |
| Observability MVP | Free telemetry loop: page views, UI errors, load metrics, an /ops page |
| Role-based access | author / editor / admin on top of Firestore Security Rules |
Веб-приложение авторской настольной ролевой системы E'Magios Core: редактор персонажа, компендиум мира и глобальный виджет бросков кубов. Дипломный проект на React + Feature-Sliced Design.
E'Magios Core — авторская настольная ролевая система. Этот репозиторий — её цифровой контур: веб-приложение игрока на React + Feature-Sliced Design и инженерный конвейер публикации контента. Выполнен как выпускная квалификационная работа.
Что демонстрирует проект: Feature-Sliced Design в боевом масштабе, конвейер «контент как данные» с аудитом и версионированием, ролевую модель доступа поверх Firestore, офлайн-кэш в IndexedDB и zero-cost деплой под защитой CI quality gate.
| Возможность | Описание |
|---|---|
| Редактор персонажа | Полнофункциональный лист персонажа с расчётами, экипировкой и навыками |
| Компендиум | База данных мира: заклинания, существа, предметы, школы магии — с перекрёстными ссылками |
| Броски кубов | Глобальный виджет дайсов с историей бросков и настройками |
| Контентный workflow | Статусная модель публикации с аудитом и версионированием |
| Observability MVP | Бесплатный контур телеметрии: page views, ошибки UI, метрики загрузок, страница /ops |
| Ролевой доступ | author / editor / admin поверх Firestore Security Rules |
For developers
flowchart TD
ContentSource[Markdown & JSON sources] --> ImportScripts[Import scripts]
ImportScripts --> DraftDocs[status: draft]
DraftDocs --> ReviewDocs[status: review]
ReviewDocs --> PublishedDocs[status: published]
PublishedDocs --> FirestoreRuntime[Firestore runtime]
FirestoreRuntime --> WebApp[React Web App]
WebApp --> IndexedDBCache[IndexedDB cache]
WebApp --> OpsMetrics[Ops / Observability]
DevPush[Push or PR] --> CIQualityGate[CI Quality Gate]
CIQualityGate --> DeployPages[Deploy GitHub Pages]
The project is structured as a hybrid of three layers:
- Content pipeline (
scripts/data-pipeline,scripts/import-content) — normalization and validation of sources, adraft → review → published → archivedstatus workflow, content versioning, and a publication audit. - Serverless backend — Firebase Auth + Firestore with a role-based access model in
firestore.rules; the app reads published documents only. - Web app (
apps/web) — React + TypeScript + Vite on a Feature-Sliced Design architecture, with an offline cache in IndexedDB and its own observability loop.
| Frontend | React 18, TypeScript 5, Vite 5, React Router 6 |
| Architecture | Feature-Sliced Design |
| Backend | Firebase Auth + Cloud Firestore |
| Cache / offline | IndexedDB (via idb) |
| Content pipeline | TypeScript (tsx) + Python |
| Quality | ESLint 9, Prettier 3, Vitest 2, Testing Library |
| CI/CD | GitHub Actions + GitHub Pages |
E-Magios-Core-Site/
├── apps/web/ # React + TypeScript + Vite (Feature-Sliced Design)
├── scripts/import-content/ # Firestore import + workflow + smoke checks
├── scripts/data-pipeline/ # normalize / validate / relations / report
├── data/ # source JSON for import
├── reports/ # generated validation and data reports
├── docs/ # project documentation and UX audit
├── .github/workflows/ # CI and deploy
├── firestore.rules # role-based access model
└── firestore.indexes.json # Firestore indexes
Web app:
cd apps/web
npm install
npm run devImport scripts:
cd scripts/import-content
npm install
npm run checkData processing:
python scripts/data-pipeline/process_data.py --no-fail-on-errorsImporting into Firestore requires
scripts/import-content/service-account.json.
apps/web:
npm run lint
npm run format:check
npm run typecheck
npm run test
npm run check # aggregatorscripts/import-content:
npm run typecheck
npm run smoke
npm run check # aggregator| Workflow | Trigger | Purpose |
|---|---|---|
.github/workflows/ci.yml |
pull_request, push to main/dev |
Install dependencies, run check + build for apps/web and import-content, generate data-pipeline reports, verify artifacts |
.github/workflows/deploy.yml |
push to main |
Build apps/web → publish dist-react to GitHub Pages |
Supported statuses: draft, review, published, archived. Transitions run through scripts/import-content/content-workflow.ts; the audit trail is written to content_publication_log.
cd scripts/import-content
npm run workflow:submit-review
npm run workflow:publish
npm run workflow:archivedoc.versionis incremented only on a real payload change;- unchanged documents keep their previous version;
- the
contentManifest/productionmanifest updatescollections.<name>.version,contentRevision,release.version,release.tag,release.changedCollections, andrelease.changedDocs.
A free observability loop:
ErrorBoundaryrecords UI failures toclient_telemetry;- routing writes
page_view; - data loads write
cache_hit,data_fetch_success,data_fetch_error; - the
/opspage shows recent telemetry events, publication logs, and an aggregated summary.
firestore.rules support the author, editor, and admin roles. For content collections:
- public read only when
status == "published"; - create/update are restricted by role and by allowed status transitions;
content_publication_logandclient_telemetryare readable only byeditor/admin;client_telemetryallowscreateonly for authenticated users.
© 2026 Гайдарь М.Д. (Max Gaida). All rights reserved.
This repository is public for portfolio and demonstration purposes only. No license is granted to use, copy, modify, or distribute any part of it without prior written permission from the author.
See LICENSE.md for details.



