Add initial JSON data files and implement core page components for game functionality

This commit is contained in:
bobbert committed 2026-03-17 21:49:44 +00:00
1 parent 81847a9188
commit ca27f8d6ed
54 files changed
+2424 -250

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
# Database Structure
This project uses split JSON files in `DB/` so each collection behaves like its own REST endpoint.
## Purpose
- Keep data modular and readable.
- Mirror server-side endpoint structure before moving to a hosted REST API.
- Allow the app to load all collections into one in-memory state via `app/Model/DbController.js`.
## Files
- `users.json`: user accounts and role state (`Uid`, `Gid`, `SGid`, `TGid`, `IsAcceptedAdmin`).
- `groups.json`: top-level game groups (`Gid`), admin approvals, and group settings.
- `subgroups.json`: subgroup definitions within each group (`SGid` scoped by `Gid`), join codes, cache trigger defaults.
- `subgroup-memberships.json`: membership bridge from `Uid` to `Gid`/`SGid`.
- `admin-waitlist.json`: pending admin requests for groups when active admins already exist.
- `teams.json`: team entities for non-admin subgroup players.
- `team-members.json`: membership bridge from `Uid` to `Tid`.
- `game-data.json`: per-group game payloads (geocaches, map/game objects).
- `game-types.json`: available game type options for UI flow.
- `db.json`: index file listing split JSON resources.
## ID Rules
- `Uid`: unique user ID.
- `Gid`: unique group/game ID.
- `SGid`: subgroup ID within a group (`0` is admin subgroup).
- `Tid`: unique team ID.
- New IDs are generated from the max existing value in each endpoint collection (`users`, `groups`, `teams`) so no separate counter file is required.
## Admin Logic
- Group creator is set as admin (`SGid = 0`) and accepted.
- New admin join requests go into `admin-waitlist.json` if active admins exist.
- If no active admin exists, the requester is auto-promoted to accepted admin.
- Group-level `ApprovedAdmins` stores accepted admin `Uid` values.
## Timestamp Format
- `CreatedAt` values are stored at minute precision:
- format: `YYYY-MM-DDTHH:mmZ`
- example: `2026-03-17T14:42Z`
+2
View File
@@ -0,0 +1,2 @@
[]
+12 -43
View File
@@ -1,45 +1,14 @@
{
"users": [
{
"Uid": 1,
"username": "admin",
"password": "admin123",
"Gid": null,
"SGid": 0,
"TGid": null
},
{
"Uid": 2,
"username": "user1",
"password": "user123",
"Gid": 1,
"SGid": 1,
"TGid": null
}
],
"groups": [
{
"Gid": 1,
"GroupName": "Public Group"
}
],
"subgroups": [
{
"SGid": 0,
"SubGroupName": "Admin Subgroup",
"Gid": null
},
{
"SGid": 1,
"SubGroupName": "User Subgroup",
"Gid": 1
}
],
"user_groups": [
{
"Uid": 2,
"Gid": 1,
"SGid": 1
}
]
"databaseMode": "split-endpoints",
"index": {
"users": "users.json",
"groups": "groups.json",
"subgroups": "subgroups.json",
"subgroup_memberships": "subgroup-memberships.json",
"admin_waitlist": "admin-waitlist.json",
"teams": "teams.json",
"team_members": "team-members.json",
"game_data": "game-data.json",
"game_types": "game-types.json"
}
}
+16
View File
@@ -0,0 +1,16 @@
[
{
"Gid": 1,
"GeoCaches": [
{
"CacheId": "C1",
"Title": "Main Entrance",
"Latitude": 0,
"Longitude": 0,
"TriggerMeters": 20,
"SGid": 1
}
]
}
]
+6
View File
@@ -0,0 +1,6 @@
[
"Join Global Game",
"Join Private Game",
"Manage Private Game"
]
+15
View File
@@ -0,0 +1,15 @@
[
{
"Gid": 1,
"GroupName": "Main Private Game",
"BusinessOrSchoolName": "MAD Academy",
"GameType": "private",
"AdminJoinCode": "A91TQ",
"CreatedByUid": 1,
"MaxMemberSubgroups": 1,
"TeamsEnabled": true,
"ApprovedAdmins": [1],
"CreatedAt": "2026-03-17T00:00Z"
}
]
-27
View File
@@ -1,27 +0,0 @@
CREATE TABLE USER (
Uid INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
username TEXT NOT NULL,
password TEXT NOT NULL
);
CREATE TABLE "GROUP" (
Gid INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
GroupName TEXT NOT NULL
);
CREATE TABLE SUBGROUP (
SGid INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
SubGroupName TEXT NOT NULL,
Gid INTEGER NOT NULL,
FOREIGN KEY (Gid) REFERENCES "GROUP"(Gid)
);
CREATE TABLE USER_GROUP (
Uid INTEGER NOT NULL,
Gid INTEGER NOT NULL,
SGid INTEGER,
PRIMARY KEY (Uid, Gid),
FOREIGN KEY (Uid) REFERENCES USER(Uid),
FOREIGN KEY (Gid) REFERENCES "GROUP"(Gid),
FOREIGN KEY (SGid) REFERENCES SUBGROUP(SGid)
);
+15
View File
@@ -0,0 +1,15 @@
[
{
"Uid": 1,
"Gid": 1,
"SGid": 0,
"IsAcceptedAdmin": true
},
{
"Uid": 2,
"Gid": 1,
"SGid": 1,
"IsAcceptedAdmin": false
}
]
+19
View File
@@ -0,0 +1,19 @@
[
{
"SGid": 0,
"SubGroupName": "Admins",
"Gid": 1,
"JoinCode": null,
"IsAdminGroup": true,
"CacheTriggerMeters": 20
},
{
"SGid": 1,
"SubGroupName": "Members",
"Gid": 1,
"JoinCode": "M4P8R",
"IsAdminGroup": false,
"CacheTriggerMeters": 20
}
]
+2
View File
@@ -0,0 +1,2 @@
[]
+2
View File
@@ -0,0 +1,2 @@
[]
+25
View File
@@ -0,0 +1,25 @@
[
{
"Uid": 1,
"username": "admin",
"email": "admin@mad.local",
"passwordHash": "H_145737963",
"isBusiness": true,
"IsAcceptedAdmin": true,
"Gid": 1,
"SGid": 0,
"TGid": null
},
{
"Uid": 2,
"username": "member1",
"email": "member1@mad.local",
"passwordHash": "H_1322967599",
"isBusiness": false,
"IsAcceptedAdmin": false,
"Gid": 1,
"SGid": 1,
"TGid": null
}
]