Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
functions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Firebase Tools
run: npm i -g firebase-tools
- name: Install deps
working-directory: functions
run: npm ci
- name: Build
working-directory: functions
run: npm run build
- name: Test (Rules on Emulator)
working-directory: functions
env:
CI: true
run: npm test
23 changes: 23 additions & 0 deletions .github/workflows/ios.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: iOS

on:
pull_request:
branches: [ main ]
workflow_dispatch:

jobs:
ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
- name: Install Fastlane
run: |
gem install fastlane
- name: Run tests
working-directory: ios
run: fastlane test
8 changes: 4 additions & 4 deletions .taskmaster/tasks/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
"description": "Create staging Firebase project and local Emulator Suite for Auth/Firestore/Functions/Storage.",
"details": "- Create Firebase project 'resilientme-staging'\n- Enable Auth (Email link, Anonymous), Firestore, Storage, FCM\n- Initialize repo configs: .firebaserc, firebase.json, firestore.indexes.json, firestore.rules\n- Configure Emulator Suite ports and UI\n- Add staging GoogleService-Info.plist and switchable build config",
"testStrategy": "Emulators boot, sample read/write works, app points to staging plist and connects",
"status": "in-progress",
"status": "done",
"dependencies": [],
"priority": "high",
"subtasks": []
Expand All @@ -249,7 +249,7 @@
"description": "Implement onCreate trigger to update aggregates, recompute resilience score, and schedule follow-up notifications.",
"details": "- onCreate users/{uid}/rejections/{id}\n- Update daily/weekly aggregate docs\n- Compute resilience score\n- Schedule 24h follow-up (FCM)",
"testStrategy": "Function unit tests with emulator; aggregates updated; notification enqueued",
"status": "pending",
"status": "done",
"dependencies": [21,22],
"priority": "high",
"subtasks": []
Expand Down Expand Up @@ -326,7 +326,7 @@
"description": "Register device tokens, handle notification taps, schedule reminders via Functions.",
"details": "- Save token under users/{uid}\n- Handle deep-links from notifications\n- Verify schedules in emulator",
"testStrategy": "Token registered; push received; open tracked; schedules fire in emulator",
"status": "pending",
"status": "in-progress",
"dependencies": [21,23],
"priority": "medium",
"subtasks": []
Expand All @@ -348,7 +348,7 @@
"description": "Define analytics schema and wire events across app.",
"details": "- Events: rejection_log, challenge_complete, community_post, reaction_add, notification_open\n- Parameter schema and validation",
"testStrategy": "Events visible in DebugView; params as designed",
"status": "pending",
"status": "in-progress",
"dependencies": [21],
"priority": "medium",
"subtasks": []
Expand Down
7 changes: 7 additions & 0 deletions firestore.indexes.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
"fields": [
{ "fieldPath": "createdAt", "order": "DESCENDING" }
]
},
{
"collectionGroup": "rejections",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "timestamp", "order": "DESCENDING" }
]
}
],
"fieldOverrides": []
Expand Down
26 changes: 24 additions & 2 deletions firestore.rules
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// User data: only owner can read/write
match /users/{userId}/{document=**} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}

// Allow functions to manage internal subcollections under users (tokens/queue)
match /users/{userId}/fcmTokens/{tokenId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
match /users/{userId}/notificationQueue/{jobId} {
// Users should not read queue jobs; functions write and later update via Admin SDK
allow read: if false;
allow create: if request.auth != null && request.auth.uid == userId;
allow update, delete: if false; // Only Admin SDK (server) should update status
}

// Community collection
match /community/{postId} {
allow read: if true;
allow create: if request.auth != null && request.resource.data.size() < 2048;
allow update, delete: if request.auth != null && request.auth.uid == resource.data.authorUid;
allow create: if request.auth != null && request.resource.data.size() < 2048
&& request.resource.data.type is string
&& request.resource.data.content is string
&& request.resource.data.createdAt != null;

// Allow reaction-only updates by any authed user
allow update: if request.auth != null && request.writeFields.all(f => f.matches('reactions(\\..+)?'));

// Only author can delete
allow delete: if request.auth != null && request.auth.uid == resource.data.authorUid;
}
}
}
12 changes: 12 additions & 0 deletions functions/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
testEnvironment: 'node',
verbose: true,
roots: ['<rootDir>/tests'],
transform: {
'^.+\\.(ts|tsx)$': [
'ts-jest',
{ tsconfig: { target: 'ES2020' } }
]
},
moduleFileExtensions: ['ts', 'js', 'json']
};
144 changes: 138 additions & 6 deletions functions/lib/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading