Skip to content

Commit 0d28fdb

Browse files
authored
Merge pull request #59 from brazostech/worktree-fix-ip-forward-startup
fix: enable ip_forward in startup sysctl config
2 parents e5e7778 + f03e884 commit 0d28fdb

48 files changed

Lines changed: 2740 additions & 930 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/work-on-issue/SKILL.md

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,13 @@ Use the appropriate type: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `c
109109

110110
```markdown
111111
## Summary
112+
112113
- <1-3 bullet points describing the changes>
113114

114115
Closes #$ARGUMENTS
115116

116117
## Test plan
118+
117119
- [ ] `npm run build` passes
118120
- [ ] `npm run lint` passes
119121
- [ ] Manual verification of <specific things to check>
@@ -130,6 +132,7 @@ Generated with [Claude Code](https://claude.com/claude-code)
130132
After the PR is created, wait for CI checks to complete and fix any failures.
131133

132134
1. Watch for CI completion:
135+
133136
```
134137
gh pr checks <PR-number> --repo The-Read-Onlys/cscs.dev --watch
135138
```
@@ -138,13 +141,17 @@ After the PR is created, wait for CI checks to complete and fix any failures.
138141

139142
3. **If any check fails** (max 3 fix attempts):
140143
a. Identify failures:
141-
```
142-
gh pr checks <PR-number> --repo The-Read-Onlys/cscs.dev --json name,state,bucket
143-
```
144+
145+
```
146+
gh pr checks <PR-number> --repo The-Read-Onlys/cscs.dev --json name,state,bucket
147+
```
148+
144149
b. Get failure logs:
145-
```
146-
gh run view <run-id> --repo The-Read-Onlys/cscs.dev --log-failed
147-
```
150+
151+
```
152+
gh run view <run-id> --repo The-Read-Onlys/cscs.dev --log-failed
153+
```
154+
148155
c. Fix the failures in the worktree.
149156
d. Re-run Step 6 (Verify) locally to confirm the fix.
150157
e. Stage specific files, commit with a message like `fix: resolve CI failure in <check-name>`, and push.
@@ -165,13 +172,13 @@ Ask the user: "Should I close issue #$ARGUMENTS now, or let the PR merge close i
165172

166173
## Error Handling
167174

168-
| Scenario | Action |
169-
|---|---|
170-
| Issue not found | Stop immediately, tell the user |
171-
| Worktree name conflict | Ask user for alternative name |
172-
| Build fails | Fix errors, re-run build |
173-
| Lint fails | Fix errors, re-run lint |
174-
| Push rejected | Pull with rebase, resolve conflicts, push again |
175-
| PR already exists for branch | Show existing PR URL, ask user how to proceed |
176-
| CI check fails | Inspect logs, fix errors, push fix, re-monitor (max 3 attempts) |
177-
| CI monitoring timeout | Tell user to check CI manually, provide PR link |
175+
| Scenario | Action |
176+
| ---------------------------- | --------------------------------------------------------------- |
177+
| Issue not found | Stop immediately, tell the user |
178+
| Worktree name conflict | Ask user for alternative name |
179+
| Build fails | Fix errors, re-run build |
180+
| Lint fails | Fix errors, re-run lint |
181+
| Push rejected | Pull with rebase, resolve conflicts, push again |
182+
| PR already exists for branch | Show existing PR URL, ask user how to proceed |
183+
| CI check fails | Inspect logs, fix errors, push fix, re-monitor (max 3 attempts) |
184+
| CI monitoring timeout | Tell user to check CI manually, provide PR link |

AUDIT.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ Comprehensive audit of the CSCS community website (cscs.dev) covering project he
1212

1313
## Project Stats
1414

15-
| Metric | Count |
16-
|--------|-------|
17-
| Pages | 13 (5 public, 8 authenticated/app) |
18-
| React Components | 12 custom + 28 Catalyst UI Kit |
19-
| Blog Posts | 3 published |
20-
| Test Files | 2 (EventForm: 50+ tests, PocketBase RSVP) |
21-
| NPM Scripts | 13 |
22-
| CI Pipeline Steps | 6 (lint, format, test, build, storybook) |
15+
| Metric | Count |
16+
| ----------------- | ----------------------------------------- |
17+
| Pages | 13 (5 public, 8 authenticated/app) |
18+
| React Components | 12 custom + 28 Catalyst UI Kit |
19+
| Blog Posts | 3 published |
20+
| Test Files | 2 (EventForm: 50+ tests, PocketBase RSVP) |
21+
| NPM Scripts | 13 |
22+
| CI Pipeline Steps | 6 (lint, format, test, build, storybook) |
2323

2424
---
2525

@@ -43,79 +43,93 @@ Comprehensive audit of the CSCS community website (cscs.dev) covering project he
4343
### HIGH — Broken Links / Placeholder Pages
4444

4545
#### 1. Footer "About" link is a placeholder
46+
4647
- **File**: `src/components/Footer.tsx:5`
4748
- **Issue**: `href: "#"` — navigates nowhere
4849
- **Fix**: Create `/about` page, update link
4950

5051
#### 2. Footer "Contact" link is a placeholder
52+
5153
- **File**: `src/components/Footer.tsx:9`
5254
- **Issue**: `href: "#"` — navigates nowhere
5355
- **Fix**: Create `/contact` page, update link
5456

5557
#### 3. Newsletter "privacy policy" link is a placeholder
58+
5659
- **File**: `src/components/Newsletter.tsx:92`
5760
- **Issue**: `href="#"` — text says "Read our privacy policy" but links nowhere
5861
- **Fix**: Create `/privacy` page, update link. Especially important since the site collects emails and has user registration.
5962

6063
### HIGH — Functionality Gaps
6164

6265
#### 4. Newsletter form may not work in production
66+
6367
- **File**: `src/components/Newsletter.tsx:67`
6468
- **Issue**: Uses `data-netlify="true"` for Netlify Forms, but the site infrastructure uses Podman/PocketBase — no evidence of Netlify deployment. Form submissions may silently fail.
6569
- **Fix**: Integrate with PocketBase (newsletter collection) or a third-party email service. Verify form submissions are actually captured.
6670

6771
### MEDIUM — Code Quality
6872

6973
#### 5. Hero images lack proper decorative attributes
74+
7075
- **File**: `src/components/Hero.tsx:132,142,150,160,168`
7176
- **Issue**: 5 Unsplash images have `alt=""` but no `role="presentation"` or `aria-hidden="true"` to explicitly mark as decorative.
7277
- **Fix**: Add `role="presentation" aria-hidden="true"` to each decorative image.
7378

7479
#### 6. Copyright year is hardcoded
80+
7581
- **File**: `src/components/Footer.tsx:90`
7682
- **Issue**: `© 2025 College Station Computer Science` — will be stale in future years
7783
- **Fix**: Use `{new Date().getFullYear()}` for dynamic year
7884

7985
#### 7. Catalyst link component TODO not resolved
86+
8087
- **File**: `src/components/catalyst/link.tsx:2`
8188
- **Issue**: `// TODO: Update this component to use your client-side framework's link`
8289
- **Fix**: Since this is a static Astro site, remove the TODO or document that `<a>` tags are the correct approach.
8390

8491
#### 8. Field naming inconsistency: `time_zone` vs `timeZone`
92+
8593
- **Referenced in**: `IMPROVEMENTS.md` Phase 3 backlog
8694
- **Issue**: PocketBase uses `time_zone` (snake_case) while JS convention is `timeZone` (camelCase). No clear mapping layer.
8795
- **Fix**: Standardize naming and add explicit mapping in `src/lib/pocketbase.ts`
8896

8997
### MEDIUM — Testing
9098

9199
#### 9. Limited test coverage
100+
92101
- **Current**: Only `EventForm.test.tsx` (50+ tests) and `pocketbase.test.ts` (RSVP functions)
93102
- **Missing**: LoginForm, RegisterForm, AccountDashboard, Header, ScheduleEvents, Newsletter, Footer
94103
- **Fix**: Prioritize tests for auth components (LoginForm, RegisterForm) and ScheduleEvents
95104

96105
### MEDIUM — Documentation
97106

98107
#### 10. CLAUDE.md says "No test suite configured" — inaccurate
108+
99109
- **File**: `CLAUDE.md`
100110
- **Issue**: States "No test suite is configured" and "No test infrastructure — manual testing required." This is outdated — the project has Vitest, React Testing Library, 50+ tests, and CI-integrated testing.
101111
- **Fix**: Update CLAUDE.md with test commands and remove the outdated notes.
102112

103113
#### 11. CLAUDE.md missing auth, events, and app page documentation
114+
104115
- **File**: `CLAUDE.md`
105116
- **Issue**: Documents the original static site but not: login/register/account pages, PocketBase integration, auth store, EventForm, ScheduleEvents, AppLayout, Storybook, container setup.
106117
- **Fix**: Add sections for backend integration, auth architecture, new pages, and new components.
107118

108119
### LOW — Enhancements
109120

110121
#### 12. No RSS feed for blog
122+
111123
- **Issue**: Blog has 3 posts and content collections but no RSS feed
112124
- **Fix**: Install `@astrojs/rss`, create `src/pages/rss.xml.ts`, add autodiscovery `<link>` tag
113125

114126
#### 13. No web analytics
127+
115128
- **Issue**: No tracking configured (Google Analytics, Plausible, etc.)
116129
- **Fix**: Choose privacy-friendly analytics, add to Layout, update privacy policy
117130

118131
#### 14. No deployment documentation or CI/CD deploy step
132+
119133
- **Issue**: `astro.config.mjs` sets site to `https://cscs.dev` but there's no hosting configuration, no deploy step in CI, and no production environment docs.
120134
- **Fix**: Document production hosting, add CI deploy step, document environment variable management.
121135

AUTHENTICATION.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ podman-compose up
3434
```
3535

3636
This will:
37+
3738
- Start PocketBase on `http://localhost:8080`
3839
- Start the Astro dev server on `http://localhost:4321`
3940
- Client-side code will automatically connect to `http://localhost:8080`
@@ -53,6 +54,7 @@ cp .env.example .env
5354
```
5455

5556
Add to `.env`:
57+
5658
```env
5759
PUBLIC_POCKETBASE_URL=http://localhost:8080
5860
```
@@ -219,6 +221,7 @@ Alternatively, you can manually verify users via Admin Dashboard (Collections
219221
SendGrid wraps all email links with click tracking URLs (e.g., `url8394.cscs.dev`). This is normal behavior and the link will redirect to the actual verification URL after tracking.
220222

221223
To disable link tracking (optional):
224+
222225
1. Login to SendGrid dashboard
223226
2. Go to Settings → Tracking
224227
3. Disable "Click Tracking"

backend/MIGRATIONS.md

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ podman-compose up
2121
```
2222

2323
**Steps:**
24+
2425
1. Login to the Admin Dashboard
2526
2. Go to "Collections"
2627
3. Create or modify collections using the UI
@@ -29,6 +30,7 @@ podman-compose up
2930
6. Commit them to git
3031

3132
**Advantages:**
33+
3234
- Visual interface for schema design
3335
- Automatic migration generation
3436
- No syntax errors
@@ -46,11 +48,14 @@ cd backend
4648
This creates a file like `1234567890_migration_name.js` with the structure:
4749

4850
```javascript
49-
migrate((app) => {
50-
// Upgrade operations
51-
}, (app) => {
52-
// Downgrade operations (optional)
53-
})
51+
migrate(
52+
(app) => {
53+
// Upgrade operations
54+
},
55+
(app) => {
56+
// Downgrade operations (optional)
57+
},
58+
);
5459
```
5560

5661
### 3. Testing Migrations
@@ -78,13 +83,15 @@ Your production workflow is already configured:
7883
4. **Backups**: Your GCE block storage undergoes scheduled backups
7984

8085
**Migration Flow:**
86+
8187
```
8288
Local Changes → Git Commit → GitHub → CI/CD Build → GCE VM → Container Restart → Migrations Apply
8389
```
8490

8591
## Best Practices
8692

8793
### DO:
94+
8895
- ✅ Use Admin Dashboard for schema changes (automigrate)
8996
- ✅ Commit all migration files to git
9097
- ✅ Test migrations locally before deploying
@@ -93,6 +100,7 @@ Local Changes → Git Commit → GitHub → CI/CD Build → GCE VM → Container
93100
- ✅ Keep migrations small and focused
94101

95102
### DON'T:
103+
96104
- ❌ Manually edit the production database
97105
- ❌ Delete migration files after they've been applied
98106
- ❌ Modify migration files after committing
@@ -103,7 +111,7 @@ Local Changes → Git Commit → GitHub → CI/CD Build → GCE VM → Container
103111

104112
### Creating a New Collection
105113

106-
1. Navigate to http://localhost:8080/_/
114+
1. Navigate to http://localhost:8080/\_/
107115
2. Collections → New Collection
108116
3. Choose collection type (Base, Auth, View)
109117
4. Add fields with appropriate types
@@ -120,6 +128,7 @@ Local Changes → Git Commit → GitHub → CI/CD Build → GCE VM → Container
120128
### Creating Relationships
121129

122130
When creating a relation field:
131+
123132
- **Type**: Relation
124133
- **Collection**: Select the target collection
125134
- **Cascade Delete**: Check if deleting parent should delete children
@@ -128,6 +137,7 @@ When creating a relation field:
128137
### Adding Indexes
129138

130139
For performance or uniqueness:
140+
131141
1. Edit collection
132142
2. Scroll to "Indexes" section
133143
3. Add index SQL: `CREATE INDEX idx_name ON table (column)`
@@ -136,6 +146,7 @@ For performance or uniqueness:
136146
## Example: Events and RSVPs Schema
137147

138148
### Events Collection
149+
139150
```
140151
Collection Type: Base
141152
Name: events
@@ -153,6 +164,7 @@ Fields:
153164
```
154165

155166
### RSVPs Collection
167+
156168
```
157169
Collection Type: Base
158170
Name: rsvps
@@ -171,13 +183,15 @@ CREATE UNIQUE INDEX idx_event_user ON rsvps (event, user)
171183
For each collection, set appropriate rules:
172184

173185
**Events:**
186+
174187
- List: `@request.auth.id != ""` (authenticated users can list)
175188
- View: `@request.auth.id != ""` (authenticated users can view)
176189
- Create: `@request.auth.id != ""` (authenticated users can create)
177190
- Update: `@request.auth.id != ""` (authenticated users can update)
178191
- Delete: `@request.auth.id != ""` (authenticated users can delete)
179192

180193
**RSVPs:**
194+
181195
- List: `@request.auth.id != ""` (authenticated users can list)
182196
- View: `@request.auth.id != ""` (authenticated users can view)
183197
- Create: `@request.auth.id != "" && @request.data.user = @request.auth.id` (users can only RSVP for themselves)
@@ -187,22 +201,26 @@ For each collection, set appropriate rules:
187201
## Troubleshooting
188202

189203
### Migration fails on production
204+
190205
1. Check logs: `podman logs pocketbase`
191206
2. Verify migration file syntax
192207
3. Check if migration was already partially applied
193208
4. Use `migrate history-sync` to clean orphaned entries
194209

195210
### Migration file not generated
211+
196212
1. Ensure `--automigrate` flag is enabled (default)
197213
2. Check file permissions on `pb_migrations/` directory
198214
3. Restart PocketBase after making changes
199215

200216
### Schema out of sync
217+
201218
1. Use `./pocketbase migrate collections` to create snapshot
202219
2. Review and apply the generated migration
203220
3. Commit to git
204221

205222
### Testing locally before production
223+
206224
```bash
207225
# 1. Backup your local database
208226
cp backend/pb_data/data.db backend/pb_data/data.db.backup
@@ -219,15 +237,16 @@ cp backend/pb_data/data.db.backup backend/pb_data/data.db
219237
## TypeScript Integration
220238

221239
PocketBase generates TypeScript definitions automatically:
240+
222241
- Location: `backend/pb_data/types.d.ts`
223242
- Updated when collections change
224243
- Use these types in your frontend code:
225244

226245
```typescript
227-
import type { EventsResponse, RsvpsResponse } from '../backend/pb_data/types';
246+
import type { EventsResponse, RsvpsResponse } from "../backend/pb_data/types";
228247

229248
// Type-safe record access
230-
const event: EventsResponse = await pb.collection('events').getOne('RECORD_ID');
249+
const event: EventsResponse = await pb.collection("events").getOne("RECORD_ID");
231250
```
232251

233252
## Resources

0 commit comments

Comments
 (0)