Update pbs-membership-loe1-recipe-saving.md via n8n
This commit is contained in:
parent
ab976ea911
commit
2b3ac756b8
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
project: pbs-membership-loe1-recipe-saving
|
project: pbs-membership-loe1-recipe-saving
|
||||||
type: project-plan
|
type: project-plan
|
||||||
@ -13,8 +14,6 @@ created: 2026-04-06
|
|||||||
updated: 2026-04-06
|
updated: 2026-04-06
|
||||||
path: PBS/Tech/Projects/
|
path: PBS/Tech/Projects/
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
# PBS Membership Platform — LOE 1: Recipe Saving
|
# PBS Membership Platform — LOE 1: Recipe Saving
|
||||||
|
|
||||||
## Vision
|
## Vision
|
||||||
@ -27,9 +26,7 @@ app, and a custom LLM trained on plant-based cooking knowledge.
|
|||||||
|
|
||||||
Recipe Saving is LOE 1 — the foundational project that establishes the
|
Recipe Saving is LOE 1 — the foundational project that establishes the
|
||||||
membership infrastructure all other LOEs build on.
|
membership infrastructure all other LOEs build on.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## LOE 1 Phases Overview
|
## LOE 1 Phases Overview
|
||||||
|
|
||||||
- **Phase 0** — Ultimate Member setup (registration, login, user roles,
|
- **Phase 0** — Ultimate Member setup (registration, login, user roles,
|
||||||
@ -40,9 +37,7 @@ endpoints) ← THIS DOC
|
|||||||
- **Phase 3** — Saved recipes page in pbs-hub (frontend UI)
|
- **Phase 3** — Saved recipes page in pbs-hub (frontend UI)
|
||||||
- **Phase 4** — Collections (named groups, organize saved recipes)
|
- **Phase 4** — Collections (named groups, organize saved recipes)
|
||||||
- **Phase 5** — Polish (mobile optimization, loading states, error handling)
|
- **Phase 5** — Polish (mobile optimization, loading states, error handling)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## All 4 Lines of Effort
|
## All 4 Lines of Effort
|
||||||
|
|
||||||
| LOE | Project | Status |
|
| LOE | Project | Status |
|
||||||
@ -51,9 +46,7 @@ endpoints) ← THIS DOC
|
|||||||
| 2 | Weekly Meal Plan Viewer | Queued |
|
| 2 | Weekly Meal Plan Viewer | Queued |
|
||||||
| 3 | Whole Food Diversity Tracker | Queued |
|
| 3 | Whole Food Diversity Tracker | Queued |
|
||||||
| 4 | User Profiles & Preferences | Queued |
|
| 4 | User Profiles & Preferences | Queued |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Phase 1: Backend Foundation
|
## Phase 1: Backend Foundation
|
||||||
|
|
||||||
### Goal
|
### Goal
|
||||||
@ -63,12 +56,10 @@ frontend — just a working API testable via curl and verifiable in
|
|||||||
phpMyAdmin.
|
phpMyAdmin.
|
||||||
|
|
||||||
### Estimated Time: 4-6 hours
|
### Estimated Time: 4-6 hours
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Architecture
|
### Architecture
|
||||||
|
|
||||||
```
|
|
||||||
Sunnie browser
|
Sunnie browser
|
||||||
→ WordPress cookie (set by Ultimate Member login)
|
→ WordPress cookie (set by Ultimate Member login)
|
||||||
→ Request to pbs-hub API
|
→ Request to pbs-hub API
|
||||||
@ -76,13 +67,11 @@ Sunnie browser
|
|||||||
→ API endpoint processes request
|
→ API endpoint processes request
|
||||||
→ Writes to pbs_hub database
|
→ Writes to pbs_hub database
|
||||||
→ Returns JSON response
|
→ Returns JSON response
|
||||||
```
|
|
||||||
|
|
||||||
**Key principle:** WordPress owns identity. pbs-hub owns membership
|
**Key principle:** WordPress owns identity. pbs-hub owns membership
|
||||||
features. The only bridge is the session cookie and read-only MySQL access.
|
features. The only bridge is the session cookie and read-only MySQL access.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Database Design
|
### Database Design
|
||||||
|
|
||||||
#### New database: pbs_hub
|
#### New database: pbs_hub
|
||||||
@ -90,7 +79,7 @@ features. The only bridge is the session cookie and read-only MySQL access.
|
|||||||
**user_interactions** — generic table for all post-related user actions
|
**user_interactions** — generic table for all post-related user actions
|
||||||
(save, like, cooked, planned, rated). Serves LOE 1 now and LOEs 2-4 later.
|
(save, like, cooked, planned, rated). Serves LOE 1 now and LOEs 2-4 later.
|
||||||
|
|
||||||
```sql
|
sql
|
||||||
CREATE DATABASE pbs_hub;
|
CREATE DATABASE pbs_hub;
|
||||||
|
|
||||||
CREATE TABLE pbs_hub.user_interactions (
|
CREATE TABLE pbs_hub.user_interactions (
|
||||||
@ -102,12 +91,12 @@ CREATE TABLE pbs_hub.user_interactions (
|
|||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
UNIQUE KEY unique_action (wp_user_id, wp_post_id, action)
|
UNIQUE KEY unique_action (wp_user_id, wp_post_id, action)
|
||||||
);
|
);
|
||||||
```
|
|
||||||
|
|
||||||
**user_preferences** — key-value store for platform-specific user settings
|
**user_preferences** — key-value store for platform-specific user settings
|
||||||
(LOE 4, but created now for completeness).
|
(LOE 4, but created now for completeness).
|
||||||
|
|
||||||
```sql
|
sql
|
||||||
CREATE TABLE pbs_hub.user_preferences (
|
CREATE TABLE pbs_hub.user_preferences (
|
||||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||||
wp_user_id INT UNSIGNED NOT NULL,
|
wp_user_id INT UNSIGNED NOT NULL,
|
||||||
@ -117,11 +106,11 @@ CREATE TABLE pbs_hub.user_preferences (
|
|||||||
CURRENT_TIMESTAMP,
|
CURRENT_TIMESTAMP,
|
||||||
UNIQUE KEY unique_pref (wp_user_id, pref_key)
|
UNIQUE KEY unique_pref (wp_user_id, pref_key)
|
||||||
);
|
);
|
||||||
```
|
|
||||||
|
|
||||||
#### MySQL user (scoped permissions)
|
#### MySQL user (scoped permissions)
|
||||||
|
|
||||||
```sql
|
sql
|
||||||
CREATE USER 'pbshub_app'@'%' IDENTIFIED BY 'strong_password_here';
|
CREATE USER 'pbshub_app'@'%' IDENTIFIED BY 'strong_password_here';
|
||||||
|
|
||||||
-- Read-only on WordPress (auth + recipe display)
|
-- Read-only on WordPress (auth + recipe display)
|
||||||
@ -133,13 +122,11 @@ GRANT SELECT ON wordpress.wp_posts TO 'pbshub_app'@'%';
|
|||||||
GRANT ALL ON pbs_hub.* TO 'pbshub_app'@'%';
|
GRANT ALL ON pbs_hub.* TO 'pbshub_app'@'%';
|
||||||
|
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** Also audit existing MySQL users (pbs-api, n8n) and scope their
|
**Note:** Also audit existing MySQL users (pbs-api, n8n) and scope their
|
||||||
permissions. Stop using root for application access.
|
permissions. Stop using root for application access.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### API Endpoints
|
### API Endpoints
|
||||||
|
|
||||||
| Method | Path | Description | Auth | Tier |
|
| Method | Path | Description | Auth | Tier |
|
||||||
@ -153,16 +140,16 @@ type | Required | Free |
|
|||||||
interaction exists | Required | Free |
|
interaction exists | Required | Free |
|
||||||
|
|
||||||
**Request body (POST):**
|
**Request body (POST):**
|
||||||
```json
|
json
|
||||||
{
|
{
|
||||||
"post_id": 123,
|
"post_id": 123,
|
||||||
"action": "save",
|
"action": "save",
|
||||||
"metadata": null
|
"metadata": null
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
**Response (GET list):**
|
**Response (GET list):**
|
||||||
```json
|
json
|
||||||
{
|
{
|
||||||
"interactions": [
|
"interactions": [
|
||||||
{
|
{
|
||||||
@ -174,15 +161,13 @@ interaction exists | Required | Free |
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** The GET list endpoint joins pbs_hub.user_interactions with
|
**Note:** The GET list endpoint joins pbs_hub.user_interactions with
|
||||||
wordpress.wp_posts to return recipe title and slug. Query filters on
|
wordpress.wp_posts to return recipe title and slug. Query filters on
|
||||||
`post_status = 'publish'` and `post_type IN ('post', 'wprm_recipe')` to
|
`post_status = 'publish'` and `post_type IN ('post', 'wprm_recipe')` to
|
||||||
exclude revisions, drafts, and other post types.
|
exclude revisions, drafts, and other post types.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Auth Middleware
|
### Auth Middleware
|
||||||
|
|
||||||
Flask `before_request` middleware that:
|
Flask `before_request` middleware that:
|
||||||
@ -201,26 +186,22 @@ Flask `before_request` middleware that:
|
|||||||
- Read-only MySQL user for WordPress tables
|
- Read-only MySQL user for WordPress tables
|
||||||
- CSRF protection via Flask-WTF (for future form submissions)
|
- CSRF protection via Flask-WTF (for future form submissions)
|
||||||
- Cookie is httponly and secure (WordPress default)
|
- Cookie is httponly and secure (WordPress default)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Tier Authorization (Future-Proofed)
|
### Tier Authorization (Future-Proofed)
|
||||||
|
|
||||||
Not needed for Phase 1 (everything is free), but the pattern is established:
|
Not needed for Phase 1 (everything is free), but the pattern is established:
|
||||||
|
|
||||||
```python
|
python
|
||||||
TIER_PERMISSIONS = {
|
TIER_PERMISSIONS = {
|
||||||
"free": ["save", "like"],
|
"free": ["save", "like"],
|
||||||
"basic": ["save", "like", "planned", "cooked"],
|
"basic": ["save", "like", "planned", "cooked"],
|
||||||
"premium": ["save", "like", "planned", "cooked", "collections",
|
"premium": ["save", "like", "planned", "cooked", "collections",
|
||||||
"ai_suggest"],
|
"ai_suggest"],
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
Adding paid tiers later is a code change, not a schema change.
|
Adding paid tiers later is a code change, not a schema change.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 1 Checklist
|
### Phase 1 Checklist
|
||||||
|
|
||||||
- [ ] Create pbs_hub database on staging MySQL
|
- [ ] Create pbs_hub database on staging MySQL
|
||||||
@ -237,9 +218,7 @@ Adding paid tiers later is a code change, not a schema change.
|
|||||||
- [ ] Test all endpoints via curl
|
- [ ] Test all endpoints via curl
|
||||||
- [ ] Verify data in phpMyAdmin
|
- [ ] Verify data in phpMyAdmin
|
||||||
- [ ] Error handling and logging
|
- [ ] Error handling and logging
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Key Decisions Made
|
### Key Decisions Made
|
||||||
|
|
||||||
| Decision | Choice | Rationale |
|
| Decision | Choice | Rationale |
|
||||||
@ -264,9 +243,7 @@ dictionary gates actions in the API layer. Database doesn't know tiers
|
|||||||
exist. |
|
exist. |
|
||||||
| MySQL user | Scoped pbshub_app | Read-only on WordPress tables, full
|
| MySQL user | Scoped pbshub_app | Read-only on WordPress tables, full
|
||||||
access on pbs_hub. No more root for applications. |
|
access on pbs_hub. No more root for applications. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Open Questions
|
### Open Questions
|
||||||
|
|
||||||
- **WordPress cookie hash suffix:** Need to check wp-config.php for the
|
- **WordPress cookie hash suffix:** Need to check wp-config.php for the
|
||||||
@ -276,12 +253,8 @@ site URL)
|
|||||||
post type or as regular 'post' with recipe metadata
|
post type or as regular 'post' with recipe metadata
|
||||||
- **pbs-hub deployment:** Does this extend the existing pbs-hub container
|
- **pbs-hub deployment:** Does this extend the existing pbs-hub container
|
||||||
or is Phase 1 a standalone Flask app for testing?
|
or is Phase 1 a standalone Flask app for testing?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Next Step: Create pbs_hub database and tables on staging, then build the
|
*Next Step: Create pbs_hub database and tables on staging, then build the
|
||||||
auth middleware*
|
auth middleware*
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
...sent from Jenny & Travis
|
...sent from Jenny & Travis
|
||||||
Loading…
Reference in New Issue
Block a user