Files
Munich-news/docs/SUBSCRIBER_STATUS.md
2025-11-11 17:40:29 +01:00

291 lines
5.7 KiB
Markdown

# Subscriber Status System
## Overview
The newsletter system tracks subscribers with a `status` field that determines whether they receive newsletters.
## Status Field
### Database Schema
```javascript
{
_id: ObjectId("..."),
email: "user@example.com",
subscribed_at: ISODate("2025-11-11T15:50:29.478Z"),
status: "active" // or "inactive"
}
```
### Status Values
| Status | Description | Receives Newsletters |
|--------|-------------|---------------------|
| `active` | Subscribed and active | ✅ Yes |
| `inactive` | Unsubscribed | ❌ No |
## How It Works
### Subscription Flow
```
User subscribes
POST /api/subscribe
Create subscriber with status: 'active'
User receives newsletters
```
### Unsubscription Flow
```
User unsubscribes
POST /api/unsubscribe
Update subscriber status: 'inactive'
User stops receiving newsletters
```
### Re-subscription Flow
```
Previously unsubscribed user subscribes again
POST /api/subscribe
Update status: 'active' + new subscribed_at date
User receives newsletters again
```
## API Endpoints
### Subscribe
```bash
curl -X POST http://localhost:5001/api/subscribe \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
```
**Creates subscriber with:**
- `email`: user@example.com
- `status`: "active"
- `subscribed_at`: current timestamp
### Unsubscribe
```bash
curl -X POST http://localhost:5001/api/unsubscribe \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
```
**Updates subscriber:**
- `status`: "inactive"
## Newsletter Sending
### Who Receives Newsletters
Only subscribers with `status: 'active'` receive newsletters.
**Sender Service Query:**
```python
subscribers_collection.find({'status': 'active'})
```
**Admin API Query:**
```python
subscribers_collection.count_documents({'status': 'active'})
```
### Testing
```bash
# Check active subscriber count
curl http://localhost:5001/api/admin/stats | jq '.subscribers'
# Output:
# {
# "total": 10,
# "active": 8
# }
```
## Database Operations
### Add Active Subscriber
```javascript
db.subscribers.insertOne({
email: "user@example.com",
subscribed_at: new Date(),
status: "active"
})
```
### Deactivate Subscriber
```javascript
db.subscribers.updateOne(
{ email: "user@example.com" },
{ $set: { status: "inactive" } }
)
```
### Reactivate Subscriber
```javascript
db.subscribers.updateOne(
{ email: "user@example.com" },
{ $set: {
status: "active",
subscribed_at: new Date()
}}
)
```
### Query Active Subscribers
```javascript
db.subscribers.find({ status: "active" })
```
### Count Active Subscribers
```javascript
db.subscribers.countDocuments({ status: "active" })
```
## Common Issues
### Issue: Stats show 0 active subscribers but subscribers exist
**Cause:** Old bug where stats checked `{active: true}` instead of `{status: 'active'}`
**Solution:** Fixed in latest version. Stats now correctly query `{status: 'active'}`
**Verify:**
```bash
# Check database directly
docker-compose exec mongodb mongosh munich_news -u admin -p changeme \
--authenticationDatabase admin \
--eval "db.subscribers.find({status: 'active'}).count()"
# Check via API
curl http://localhost:5001/api/admin/stats | jq '.subscribers.active'
```
### Issue: Newsletter not sending to subscribers
**Possible causes:**
1. Subscribers have `status: 'inactive'`
2. No subscribers in database
3. Email configuration issue
**Debug:**
```bash
# Check subscriber status
docker-compose exec mongodb mongosh munich_news -u admin -p changeme \
--authenticationDatabase admin \
--eval "db.subscribers.find().pretty()"
# Check active count
curl http://localhost:5001/api/admin/stats | jq '.subscribers'
# Try sending
curl -X POST http://localhost:5001/api/admin/send-newsletter \
-H "Content-Type: application/json"
```
## Migration Notes
### If you have old subscribers without status field
Run this migration:
```javascript
// Set all subscribers without status to 'active'
db.subscribers.updateMany(
{ status: { $exists: false } },
{ $set: { status: "active" } }
)
```
### If you have subscribers with `active: true/false` field
Run this migration:
```javascript
// Convert old 'active' field to 'status' field
db.subscribers.updateMany(
{ active: true },
{ $set: { status: "active" }, $unset: { active: "" } }
)
db.subscribers.updateMany(
{ active: false },
{ $set: { status: "inactive" }, $unset: { active: "" } }
)
```
## Best Practices
### 1. Always Check Status
When querying subscribers for sending:
```python
# ✅ Correct
subscribers_collection.find({'status': 'active'})
# ❌ Wrong
subscribers_collection.find({}) # Includes inactive
```
### 2. Soft Delete
Never delete subscribers - just set status to 'inactive':
```python
# ✅ Correct - preserves history
subscribers_collection.update_one(
{'email': email},
{'$set': {'status': 'inactive'}}
)
# ❌ Wrong - loses data
subscribers_collection.delete_one({'email': email})
```
### 3. Track Subscription History
Consider adding fields:
```javascript
{
email: "user@example.com",
status: "active",
subscribed_at: ISODate("2025-01-01"),
unsubscribed_at: null, // Set when status changes to inactive
resubscribed_count: 0 // Increment on re-subscription
}
```
### 4. Validate Before Sending
```python
# Check subscriber count before sending
count = subscribers_collection.count_documents({'status': 'active'})
if count == 0:
return {'error': 'No active subscribers'}
```
## Related Documentation
- [ADMIN_API.md](ADMIN_API.md) - Admin API endpoints
- [DATABASE_SCHEMA.md](DATABASE_SCHEMA.md) - Complete database schema
- [NEWSLETTER_API_UPDATE.md](../NEWSLETTER_API_UPDATE.md) - Newsletter API changes