Refactor project structure and remove outdated documentation
Browse files- Deleted backend_structure.md, component_architecture.md, deployment_architecture.md, development_roadmap.md, frontend_requirements.md, frontend_structure.md to streamline project documentation.
- Updated Posts.jsx to handle new post generation result structure.
- Modified postService.js to accommodate changes in the generated content and image handling.
- Adjusted postsSlice.js to ensure proper handling of generated post results.
- Updated package.json to improve development command scripts and ensure compatibility.
- Introduced starty.py as a universal startup script for development servers, simplifying the process of starting frontend and backend.
- Added test_imports.py to verify backend imports and ensure proper module accessibility.
- .gitignore +3 -0
- ACCOUNT_CREATION_ANALYSIS_SUMMARY.md +0 -97
- ACCOUNT_CREATION_DIAGNOSTICS.md +0 -91
- ACCOUNT_CREATION_FINAL_FIX.md +0 -201
- ACCOUNT_CREATION_FIX_PLAN.md +0 -166
- ACCOUNT_CREATION_FIX_SUMMARY.md +0 -184
- ACCOUNT_CREATION_WORKFLOW.md +0 -150
- CELERY_SCHEDULING_SETUP.md +0 -340
- DEPLOYMENT_VERIFICATION_CHECKLIST.md +0 -165
- FINAL_APSCHEDULER_MIGRATION_SUMMARY.md +0 -60
- FINAL_DOCUMENTATION.md +0 -692
- LINKEDIN_AUTH_GUIDE.md +0 -258
- MIGRATION_TO_APSCHEDULER.md +0 -84
- api_design.md +0 -348
- architecture_summary.md +0 -111
- backend/TASK_SCHEDULING_EVOLUTION.md +0 -124
- backend/api/posts.py +71 -30
- backend/app.py +12 -4
- backend/services/__init__.py +2 -0
- backend/services/content_service.py +27 -21
- backend_requirements.md +0 -163
- backend_structure.md +0 -78
- component_architecture.md +0 -237
- deployment_architecture.md +0 -235
- development_roadmap.md +0 -312
- frontend/src/pages/Posts.jsx +6 -18
- frontend/src/services/postService.js +24 -6
- frontend/src/store/reducers/postsSlice.js +1 -0
- frontend_requirements.md +0 -235
- frontend_structure.md +0 -93
- package.json +4 -4
- starty.py +145 -0
- test_imports.py +36 -0
.gitignore
CHANGED
@@ -164,5 +164,8 @@ Thumbs.db
|
|
164 |
# Supabase
|
165 |
supabase/.temp/
|
166 |
|
|
|
|
|
|
|
167 |
# Docker
|
168 |
docker-compose.override.yml
|
|
|
164 |
# Supabase
|
165 |
supabase/.temp/
|
166 |
|
167 |
+
# Serena
|
168 |
+
.serena/
|
169 |
+
|
170 |
# Docker
|
171 |
docker-compose.override.yml
|
ACCOUNT_CREATION_ANALYSIS_SUMMARY.md
DELETED
@@ -1,97 +0,0 @@
|
|
1 |
-
# Account Creation Issue Analysis Summary
|
2 |
-
|
3 |
-
## Problem Statement
|
4 |
-
Users are unable to see LinkedIn accounts in their database despite successful OAuth authentication. The OAuth flow completes successfully, but accounts are not being saved to the database.
|
5 |
-
|
6 |
-
## Investigation Results
|
7 |
-
|
8 |
-
### ✅ What's Working
|
9 |
-
1. **OAuth Authentication**: LinkedIn OAuth flow is working correctly
|
10 |
-
2. **Frontend Callback**: LinkedInCallbackHandler processes the callback properly
|
11 |
-
3. **API Endpoints**: GET /api/accounts returns successful responses
|
12 |
-
4. **Database Queries**: Supabase queries are executing successfully
|
13 |
-
|
14 |
-
### ❌ What's Not Working
|
15 |
-
1. **Database Insertion**: OAuth callback handler fails to insert accounts into Social_network table
|
16 |
-
2. **Error Handling**: Silent failures prevent proper debugging
|
17 |
-
3. **Logging**: Insufficient logging to track the insertion process
|
18 |
-
|
19 |
-
## Root Cause
|
20 |
-
The OAuth callback handler in [`backend/api/accounts.py:126-207`](backend/api/accounts.py:126) is not successfully inserting account data into the Supabase database. The handler receives the OAuth code and processes it correctly, but the database insertion step is failing silently.
|
21 |
-
|
22 |
-
## Key Findings
|
23 |
-
|
24 |
-
### Log Analysis
|
25 |
-
- **Successful Operations**: Multiple GET /api/accounts requests (200 responses)
|
26 |
-
- **Successful OAuth**: LinkedIn callback with authorization code received
|
27 |
-
- **Missing Evidence**: No logs showing successful database insertion
|
28 |
-
- **Silent Failures**: Error handling may be suppressing exceptions
|
29 |
-
|
30 |
-
### Technical Issues
|
31 |
-
1. **Insufficient Logging**: No detailed logs in the OAuth callback handler
|
32 |
-
2. **Silent Failures**: Database errors may be caught and suppressed
|
33 |
-
3. **Missing Verification**: No confirmation that insertion was successful
|
34 |
-
4. **Error Handling**: Generic error messages don't provide specific feedback
|
35 |
-
|
36 |
-
## Recommended Solution
|
37 |
-
|
38 |
-
### Immediate Actions (Priority: High)
|
39 |
-
1. **Add Enhanced Logging** to the OAuth callback handler
|
40 |
-
2. **Verify Database Connection** and permissions
|
41 |
-
3. **Test Database Insertion** with sample data
|
42 |
-
4. **Implement Proper Error Handling** with detailed feedback
|
43 |
-
|
44 |
-
### Implementation Plan
|
45 |
-
1. **Phase 1**: Debugging and Logging (1-2 days)
|
46 |
-
2. **Phase 2**: Database Verification (1 day)
|
47 |
-
3. **Phase 3**: Error Handling Enhancement (1 day)
|
48 |
-
4. **Phase 4**: Testing and Verification (1-2 days)
|
49 |
-
|
50 |
-
## Files Requiring Changes
|
51 |
-
|
52 |
-
### Backend Files
|
53 |
-
- [`backend/api/accounts.py`](backend/api/accounts.py) - OAuth callback handler
|
54 |
-
- [`backend/services/linkedin_service.py`](backend/services/linkedin_service.py) - LinkedIn API integration
|
55 |
-
- [`backend/utils/database.py`](backend/utils/database.py) - Database utilities
|
56 |
-
|
57 |
-
### Frontend Files
|
58 |
-
- [`frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx`](frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx) - Callback processing
|
59 |
-
- [`frontend/src/services/accountService.js`](frontend/src/services/accountService.js) - API client
|
60 |
-
|
61 |
-
## Success Criteria
|
62 |
-
1. ✅ OAuth callback completes successfully
|
63 |
-
2. ✅ Account data is properly inserted into database
|
64 |
-
3. ✅ Account appears in user account list
|
65 |
-
4. ✅ Error handling provides clear feedback
|
66 |
-
5. ✅ Comprehensive logging for debugging
|
67 |
-
|
68 |
-
## Risk Assessment
|
69 |
-
- **High Risk**: Database connection or permission issues
|
70 |
-
- **Medium Risk**: RLS policy conflicts
|
71 |
-
- **Low Risk**: Frontend callback handling
|
72 |
-
|
73 |
-
## Next Steps
|
74 |
-
1. **Approve Implementation Plan**: Review and approve the proposed changes
|
75 |
-
2. **Begin Phase 1**: Add enhanced logging to OAuth callback handler
|
76 |
-
3. **Database Verification**: Check table structure and permissions
|
77 |
-
4. **Testing**: Verify the fix works end-to-end
|
78 |
-
|
79 |
-
## Documentation Created
|
80 |
-
- [`ACCOUNT_CREATION_DIAGNOSTICS.md`](ACCOUNT_CREATION_DIAGNOSTICS.md) - Detailed analysis of the issue
|
81 |
-
- [`ACCOUNT_CREATION_FIX_PLAN.md`](ACCOUNT_CREATION_FIX_PLAN.md) - Implementation plan with specific steps
|
82 |
-
- [`ACCOUNT_CREATION_WORKFLOW.md`](ACCOUNT_CREATION_WORKFLOW.md) - Visual workflow diagram
|
83 |
-
|
84 |
-
## Questions for Review
|
85 |
-
1. Should we proceed with the implementation as outlined?
|
86 |
-
2. Are there any specific concerns about the proposed changes?
|
87 |
-
3. Do you have access to the Supabase dashboard to verify database structure?
|
88 |
-
4. Should we create a backup before making changes?
|
89 |
-
|
90 |
-
## Expected Timeline
|
91 |
-
- **Implementation**: 3-5 days
|
92 |
-
- **Testing**: 1-2 days
|
93 |
-
- **Deployment**: 1 day
|
94 |
-
- **Total**: 5-8 days
|
95 |
-
|
96 |
-
## Contact Information
|
97 |
-
For questions or clarification about this analysis, please refer to the documentation files or contact the development team.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ACCOUNT_CREATION_DIAGNOSTICS.md
DELETED
@@ -1,91 +0,0 @@
|
|
1 |
-
# Account Creation Issue Analysis
|
2 |
-
|
3 |
-
## Problem Summary
|
4 |
-
User is trying to add a LinkedIn account but despite successful API calls (200 responses), the account doesn't appear in the database.
|
5 |
-
|
6 |
-
## Log Analysis
|
7 |
-
|
8 |
-
### Successful Operations Observed:
|
9 |
-
1. **GET /api/accounts** - Multiple successful requests returning 200
|
10 |
-
2. **Supabase API calls** - Successful queries to `Social_network` table
|
11 |
-
3. **POST /api/accounts** - Successful request returning 200
|
12 |
-
4. **Auth callback** - Successful OAuth callback with authorization code
|
13 |
-
|
14 |
-
### Key Issues Identified:
|
15 |
-
1. **Missing database insertion** - No logs showing successful account creation in database
|
16 |
-
2. **OAuth callback flow** - The callback handler may be failing silently
|
17 |
-
3. **Data persistence** - Accounts are being retrieved but not stored properly
|
18 |
-
|
19 |
-
## Root Cause Analysis
|
20 |
-
|
21 |
-
### 1. OAuth Callback Flow Issue
|
22 |
-
The logs show a successful auth callback:
|
23 |
-
```
|
24 |
-
GET /auth/callback?code=AQQe_UpcxzZsgqMcsO-CnPi07wyc-Uh6cv6WVwPbFWm-4MsQ-OvJCmDuyOWlvK5e_67rrpZjiunqWHLd8rv5uvDJg_T2pPhvDj6BJYzmpDF_RpktHJQnOqQEiEsuaG8ZImd_wFsRI9-6T5A3-9wYuZVQhtkwdIDsZ4Dofp54_jbyzCLUrahbzfkRlL2c29DeWvfP9jTy8bQF1AeYLEA&state=KUXEkZ7fZjsrZWxJxm4E-do2UysOvF45Kipvk00kfUM
|
25 |
-
```
|
26 |
-
|
27 |
-
But there's no corresponding log entry for the `/accounts/callback` POST request that should follow.
|
28 |
-
|
29 |
-
### 2. Database Insertion Problem
|
30 |
-
The OAuth callback handler in [`backend/api/accounts.py:169-183`](backend/api/accounts.py:169) should insert data into the `Social_network` table, but there's no evidence this is happening.
|
31 |
-
|
32 |
-
### 3. Error Handling Issues
|
33 |
-
The error handling in the OAuth callback may be swallowing exceptions and returning 200 even when failures occur.
|
34 |
-
|
35 |
-
## Diagnostic Plan
|
36 |
-
|
37 |
-
### Phase 1: Immediate Debugging
|
38 |
-
1. **Add detailed logging** to track the complete OAuth flow
|
39 |
-
2. **Verify database schema** and table structure
|
40 |
-
3. **Test database permissions** and insert operations
|
41 |
-
4. **Check user ID mapping** between auth and database
|
42 |
-
|
43 |
-
### Phase 2: Flow Verification
|
44 |
-
1. **Test the complete OAuth flow** end-to-end
|
45 |
-
2. **Verify data insertion** at each step
|
46 |
-
3. **Check for data validation** issues
|
47 |
-
4. **Test error scenarios** and edge cases
|
48 |
-
|
49 |
-
### Phase 3: Database Investigation
|
50 |
-
1. **Check existing records** in Social_network table
|
51 |
-
2. **Verify table constraints** and indexes
|
52 |
-
3. **Test manual insertion** to isolate the issue
|
53 |
-
4. **Check for triggers** or RLS policies
|
54 |
-
|
55 |
-
## Technical Architecture
|
56 |
-
|
57 |
-
### Account Creation Flow:
|
58 |
-
```
|
59 |
-
Frontend → POST /api/accounts → Initiate OAuth → Redirect to LinkedIn
|
60 |
-
LinkedIn Callback → GET /auth/callback → Frontend handles callback
|
61 |
-
Frontend → POST /accounts/callback → Backend processes OAuth code
|
62 |
-
Backend → Insert into Supabase Social_network table → Return success
|
63 |
-
```
|
64 |
-
|
65 |
-
### Key Components:
|
66 |
-
- **Frontend**: [`LinkedInCallbackHandler.jsx`](frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx)
|
67 |
-
- **Backend**: [`accounts.py`](backend/api/accounts.py) - OAuth callback handler
|
68 |
-
- **Database**: Supabase `Social_network` table
|
69 |
-
- **Service**: [`LinkedInService`](backend/services/linkedin_service.py)
|
70 |
-
|
71 |
-
## Recommended Actions
|
72 |
-
|
73 |
-
### Immediate Actions:
|
74 |
-
1. **Add debug logging** to the OAuth callback handler
|
75 |
-
2. **Verify the callback endpoint** is being called
|
76 |
-
3. **Check database connection** and permissions
|
77 |
-
4. **Test manual insertion** to isolate the issue
|
78 |
-
|
79 |
-
### Long-term Fixes:
|
80 |
-
1. **Improve error handling** to provide detailed feedback
|
81 |
-
2. **Add database validation** and constraints
|
82 |
-
3. **Implement proper logging** for all operations
|
83 |
-
4. **Add monitoring** for account creation success/failure rates
|
84 |
-
|
85 |
-
## Next Steps
|
86 |
-
|
87 |
-
1. Create a debug script to test the database connection and table structure
|
88 |
-
2. Add detailed logging to track the OAuth callback flow
|
89 |
-
3. Verify the callback endpoint is receiving the correct data
|
90 |
-
4. Test the database insertion process with sample data
|
91 |
-
5. Check for any RLS policies or triggers that might block insertion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ACCOUNT_CREATION_FINAL_FIX.md
DELETED
@@ -1,201 +0,0 @@
|
|
1 |
-
# LinkedIn Account Creation - Final Fix Summary
|
2 |
-
|
3 |
-
## Problem Solved
|
4 |
-
|
5 |
-
The user was experiencing an issue where LinkedIn accounts were not appearing in the database despite successful OAuth authentication. The logs showed that the OAuth callback was working, but the account creation process was failing.
|
6 |
-
|
7 |
-
## Root Cause
|
8 |
-
|
9 |
-
The original implementation had a complex multi-step process:
|
10 |
-
1. Backend receives OAuth callback
|
11 |
-
2. Backend stores OAuth data in session
|
12 |
-
3. Frontend redirects to callback handler
|
13 |
-
4. Frontend makes API call to complete OAuth flow
|
14 |
-
5. Backend processes OAuth data and stores account
|
15 |
-
|
16 |
-
This approach was failing because:
|
17 |
-
- The frontend callback handler was trying to make additional API calls that weren't working properly
|
18 |
-
- There was a circular dependency issue in the OAuth flow
|
19 |
-
- The session management was complex and error-prone
|
20 |
-
|
21 |
-
## Solution: Direct Backend Processing
|
22 |
-
|
23 |
-
I implemented a much simpler and more robust solution by processing the complete OAuth flow directly in the backend callback handler.
|
24 |
-
|
25 |
-
### Backend Changes (`backend/app.py`)
|
26 |
-
|
27 |
-
**Key Changes:**
|
28 |
-
1. **Complete OAuth Flow in Backend**: The `/auth/callback` endpoint now handles the entire OAuth process:
|
29 |
-
- Receives OAuth code and state from LinkedIn
|
30 |
-
- Verifies JWT token from cookies to get user ID
|
31 |
-
- Exchanges OAuth code for access token
|
32 |
-
- Fetches user information from LinkedIn API
|
33 |
-
- Stores account data directly in Supabase database
|
34 |
-
- Redirects to frontend with success/failure status
|
35 |
-
|
36 |
-
**Code Flow:**
|
37 |
-
```python
|
38 |
-
@app.route('/auth/callback')
|
39 |
-
def handle_auth_callback():
|
40 |
-
# 1. Parse OAuth parameters
|
41 |
-
code = request.args.get('code')
|
42 |
-
state = request.args.get('state')
|
43 |
-
|
44 |
-
# 2. Verify JWT and get user ID
|
45 |
-
user_data = decode_token(token)
|
46 |
-
user_id = user_data['sub']
|
47 |
-
|
48 |
-
# 3. Exchange code for access token
|
49 |
-
token_response = linkedin_service.get_access_token(code)
|
50 |
-
access_token = token_response['access_token']
|
51 |
-
|
52 |
-
# 4. Get user info
|
53 |
-
user_info = linkedin_service.get_user_info(access_token)
|
54 |
-
|
55 |
-
# 5. Store account in database
|
56 |
-
account_data = {
|
57 |
-
"social_network": "LinkedIn",
|
58 |
-
"account_name": user_info.get('name'),
|
59 |
-
"id_utilisateur": user_id,
|
60 |
-
"token": access_token,
|
61 |
-
"sub": user_info.get('sub'),
|
62 |
-
"given_name": user_info.get('given_name'),
|
63 |
-
"family_name": user_info.get('family_name'),
|
64 |
-
"picture": user_info.get('picture')
|
65 |
-
}
|
66 |
-
|
67 |
-
response = app.supabase.table("Social_network").insert(account_data).execute()
|
68 |
-
|
69 |
-
# 6. Redirect to frontend
|
70 |
-
redirect_url = f"{request.host_url.rstrip('/')}?oauth_success=true&account_linked=true&from=linkedin"
|
71 |
-
return redirect(redirect_url)
|
72 |
-
```
|
73 |
-
|
74 |
-
### Frontend Changes (`frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx`)
|
75 |
-
|
76 |
-
**Key Changes:**
|
77 |
-
1. **Simplified Callback Handler**: The frontend now just handles the redirect and displays appropriate messages
|
78 |
-
2. **No Additional API Calls**: Removed the complex session data retrieval and OAuth completion calls
|
79 |
-
3. **Direct Status Handling**: Simply checks for `oauth_success=true` and `account_linked=true` parameters
|
80 |
-
|
81 |
-
**Code Flow:**
|
82 |
-
```javascript
|
83 |
-
useEffect(() => {
|
84 |
-
const handleCallback = async () => {
|
85 |
-
const urlParams = new URLSearchParams(location.search);
|
86 |
-
const error = urlParams.get('error');
|
87 |
-
const oauthSuccess = urlParams.get('oauth_success');
|
88 |
-
const accountLinked = urlParams.get('account_linked');
|
89 |
-
const from = urlParams.get('from');
|
90 |
-
|
91 |
-
if (from === 'linkedin') {
|
92 |
-
if (error) {
|
93 |
-
setStatus('error');
|
94 |
-
setMessage(`Authentication failed: ${error}`);
|
95 |
-
} else if (oauthSuccess === 'true' && accountLinked === 'true') {
|
96 |
-
setStatus('success');
|
97 |
-
setMessage('LinkedIn account linked successfully!');
|
98 |
-
await dispatch(fetchLinkedInAccounts());
|
99 |
-
setTimeout(() => navigate('/sources'), 2000);
|
100 |
-
}
|
101 |
-
}
|
102 |
-
};
|
103 |
-
|
104 |
-
if (location.search.includes('oauth_success=') || location.search.includes('error=')) {
|
105 |
-
handleCallback();
|
106 |
-
}
|
107 |
-
}, [dispatch, location, navigate]);
|
108 |
-
```
|
109 |
-
|
110 |
-
## Benefits of the New Approach
|
111 |
-
|
112 |
-
### 1. **Simplified Architecture**
|
113 |
-
- Single point of processing in the backend
|
114 |
-
- No complex session management
|
115 |
-
- Eliminated circular dependencies
|
116 |
-
|
117 |
-
### 2. **Better Error Handling**
|
118 |
-
- Comprehensive error logging at each step
|
119 |
-
- Clear error messages for different failure scenarios
|
120 |
-
- Proper error propagation to frontend
|
121 |
-
|
122 |
-
### 3. **Improved Reliability**
|
123 |
-
- Direct database insertion from backend
|
124 |
-
- No intermediate API calls that could fail
|
125 |
-
- JWT verification ensures proper user authentication
|
126 |
-
|
127 |
-
### 4. **Enhanced Security**
|
128 |
-
- OAuth tokens never exposed to frontend
|
129 |
-
- User authentication verified before account creation
|
130 |
-
- Secure token handling in backend
|
131 |
-
|
132 |
-
### 5. **Better User Experience**
|
133 |
-
- Faster processing (no round trips to frontend)
|
134 |
-
- Clear success/failure feedback
|
135 |
-
- Automatic redirection after successful linking
|
136 |
-
|
137 |
-
## Expected Flow After Fix
|
138 |
-
|
139 |
-
1. **User Initiates OAuth**: User clicks "Connect LinkedIn Account"
|
140 |
-
2. **LinkedIn Authentication**: User is redirected to LinkedIn for authentication
|
141 |
-
3. **LinkedIn Callback**: LinkedIn redirects back to `/auth/callback` with OAuth code
|
142 |
-
4. **Backend Processing**:
|
143 |
-
- Verifies user JWT token
|
144 |
-
- Exchanges OAuth code for access token
|
145 |
-
- Fetches user information
|
146 |
-
- Stores account in database
|
147 |
-
5. **Frontend Redirect**: Backend redirects to frontend with success parameters
|
148 |
-
6. **User Feedback**: Frontend shows success message and redirects to sources page
|
149 |
-
|
150 |
-
## Testing and Verification
|
151 |
-
|
152 |
-
### Backend Logs to Check
|
153 |
-
```
|
154 |
-
🔗 [OAuth] Direct callback handler triggered
|
155 |
-
🔗 [OAuth] Processing OAuth for user: [user_id]
|
156 |
-
🔗 [OAuth] Token exchange successful
|
157 |
-
🔗 [OAuth] User info fetched
|
158 |
-
🔗 [OAuth] Prepared account data: {...}
|
159 |
-
🔗 [OAuth] Inserting account into database...
|
160 |
-
🔗 [OAuth] Account linked successfully for user: [user_id]
|
161 |
-
```
|
162 |
-
|
163 |
-
### Database Verification
|
164 |
-
After successful OAuth flow, check the `Social_network` table:
|
165 |
-
```sql
|
166 |
-
SELECT * FROM Social_network
|
167 |
-
WHERE id_utilisateur = '[user_id]'
|
168 |
-
AND social_network = 'LinkedIn';
|
169 |
-
```
|
170 |
-
|
171 |
-
### Frontend Verification
|
172 |
-
- User should see "LinkedIn account linked successfully!" message
|
173 |
-
- Account should appear in the UI after refresh
|
174 |
-
- User should be redirected to the sources page
|
175 |
-
|
176 |
-
## Troubleshooting
|
177 |
-
|
178 |
-
### Common Issues and Solutions
|
179 |
-
|
180 |
-
1. **JWT Token Verification Fails**
|
181 |
-
- Ensure user is properly authenticated
|
182 |
-
- Check that JWT token is present in cookies
|
183 |
-
|
184 |
-
2. **Token Exchange Fails**
|
185 |
-
- Verify LinkedIn API credentials in environment variables
|
186 |
-
- Check that OAuth code is not expired
|
187 |
-
|
188 |
-
3. **Database Insertion Fails**
|
189 |
-
- Verify Supabase database connection
|
190 |
-
- Check table schema and permissions
|
191 |
-
- Ensure user ID format matches database expectations
|
192 |
-
|
193 |
-
4. **Frontend Not Redirecting**
|
194 |
-
- Check that callback parameters are properly passed
|
195 |
-
- Verify frontend routing configuration
|
196 |
-
|
197 |
-
## Conclusion
|
198 |
-
|
199 |
-
This fix simplifies the entire OAuth flow by processing everything directly in the backend, eliminating the complex multi-step process that was causing the account creation to fail. The new approach is more reliable, secure, and provides better error handling and user feedback.
|
200 |
-
|
201 |
-
The key improvement is that the backend now handles the complete OAuth flow from start to finish, ensuring that accounts are properly created in the database without any intermediate steps that could fail.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ACCOUNT_CREATION_FIX_PLAN.md
DELETED
@@ -1,166 +0,0 @@
|
|
1 |
-
# Account Creation Fix Implementation Plan
|
2 |
-
|
3 |
-
## Executive Summary
|
4 |
-
The account creation process is failing during the OAuth callback phase. While the initial OAuth flow and callback are successful, the database insertion step is not working properly, resulting in accounts not being saved to the database.
|
5 |
-
|
6 |
-
## Root Cause Analysis
|
7 |
-
Based on the log analysis, the issue is in the OAuth callback handler in [`backend/api/accounts.py`](backend/api/accounts.py:126-207). The handler receives the OAuth code and state but fails to properly insert the account data into the Supabase `Social_network` table.
|
8 |
-
|
9 |
-
## Implementation Plan
|
10 |
-
|
11 |
-
### Phase 1: Immediate Debugging & Logging (Priority: High)
|
12 |
-
|
13 |
-
#### 1.1 Enhanced Logging for OAuth Callback
|
14 |
-
**File**: [`backend/api/accounts.py`](backend/api/accounts.py:126-207)
|
15 |
-
**Changes**:
|
16 |
-
- Add detailed logging at the beginning of `handle_oauth_callback`
|
17 |
-
- Log all received parameters (user_id, code, state, social_network)
|
18 |
-
- Add logging before and after database insertion
|
19 |
-
- Log the exact data being inserted
|
20 |
-
|
21 |
-
```python
|
22 |
-
# Add to handle_oauth_callback function
|
23 |
-
current_app.logger.info(f"🔗 [OAuth] Starting callback for user: {user_id}")
|
24 |
-
current_app.logger.info(f"🔗 [OAuth] Received data: {data}")
|
25 |
-
current_app.logger.info(f"🔗 [OAuth] Supabase client available: {hasattr(current_app, 'supabase')}")
|
26 |
-
```
|
27 |
-
|
28 |
-
#### 1.2 Database Connection Verification
|
29 |
-
**File**: [`backend/api/accounts.py`](backend/api/accounts.py:169-183)
|
30 |
-
**Changes**:
|
31 |
-
- Add verification that Supabase client is properly initialized
|
32 |
-
- Log the exact table name and data structure being used
|
33 |
-
- Add error handling for database connection issues
|
34 |
-
|
35 |
-
#### 1.3 Response Validation
|
36 |
-
**File**: [`backend/api/accounts.py`](backend/api/accounts.py:184-195)
|
37 |
-
**Changes**:
|
38 |
-
- Add detailed logging of the database response
|
39 |
-
- Log whether `response.data` exists and what it contains
|
40 |
-
- Add validation to ensure the insertion was successful
|
41 |
-
|
42 |
-
### Phase 2: Database Schema & Permissions (Priority: High)
|
43 |
-
|
44 |
-
#### 2.1 Table Structure Verification
|
45 |
-
**Action**: Verify the `Social_network` table structure in Supabase
|
46 |
-
**Required Fields**:
|
47 |
-
- `id` (UUID, primary key)
|
48 |
-
- `social_network` (text)
|
49 |
-
- `account_name` (text)
|
50 |
-
- `id_utilisateur` (text, foreign key to users)
|
51 |
-
- `token` (text, nullable)
|
52 |
-
- `sub` (text, nullable)
|
53 |
-
- `given_name` (text, nullable)
|
54 |
-
- `family_name` (text, nullable)
|
55 |
-
- `picture` (text, nullable)
|
56 |
-
|
57 |
-
#### 2.2 RLS (Row Level Security) Policies
|
58 |
-
**Action**: Check RLS policies on the `Social_network` table
|
59 |
-
**Expected Policy**: Users should only be able to insert/update their own records
|
60 |
-
**Verification**: Ensure the policy allows `id_utilisateur = auth.uid()`
|
61 |
-
|
62 |
-
#### 2.3 Database Permissions
|
63 |
-
**Action**: Verify service account has proper permissions
|
64 |
-
**Required Permissions**: INSERT, SELECT, UPDATE, DELETE on `Social_network` table
|
65 |
-
|
66 |
-
### Phase 3: OAuth Flow Verification (Priority: Medium)
|
67 |
-
|
68 |
-
#### 3.1 Frontend Callback Handling
|
69 |
-
**File**: [`frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx`](frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx:15-62)
|
70 |
-
**Changes**:
|
71 |
-
- Add logging to verify the callback is being processed
|
72 |
-
- Log the URL parameters (code, state, error)
|
73 |
-
- Verify the correct API endpoint is being called
|
74 |
-
|
75 |
-
#### 3.2 API Endpoint Verification
|
76 |
-
**File**: [`frontend/src/services/accountService.js`](frontend/src/services/accountService.js:82-101)
|
77 |
-
**Changes**:
|
78 |
-
- Add logging to verify the callback request is being sent
|
79 |
-
- Log the request payload and response
|
80 |
-
- Verify the correct endpoint `/accounts/callback` is being used
|
81 |
-
|
82 |
-
### Phase 4: Data Validation & Error Handling (Priority: Medium)
|
83 |
-
|
84 |
-
#### 4.1 Input Validation
|
85 |
-
**File**: [`backend/api/accounts.py`](backend/api/accounts.py:144-149)
|
86 |
-
**Changes**:
|
87 |
-
- Add comprehensive validation for all required fields
|
88 |
-
- Add logging for validation failures
|
89 |
-
- Provide specific error messages for missing fields
|
90 |
-
|
91 |
-
#### 4.2 Error Handling Enhancement
|
92 |
-
**File**: [`backend/api/accounts.py`](backend/api/accounts.py:202-207)
|
93 |
-
**Changes**:
|
94 |
-
- Add specific error logging for different failure scenarios
|
95 |
-
- Include the original error message in the response
|
96 |
-
- Add try-catch blocks around database operations
|
97 |
-
|
98 |
-
### Phase 5: Testing & Verification (Priority: Medium)
|
99 |
-
|
100 |
-
#### 5.1 Unit Testing
|
101 |
-
**Action**: Create unit tests for the OAuth callback handler
|
102 |
-
**Coverage**:
|
103 |
-
- Successful OAuth flow
|
104 |
-
- Missing required fields
|
105 |
-
- Database connection failures
|
106 |
-
- Invalid user ID
|
107 |
-
|
108 |
-
#### 5.2 Integration Testing
|
109 |
-
**Action**: Test the complete OAuth flow end-to-end
|
110 |
-
**Steps**:
|
111 |
-
1. Initiate OAuth flow
|
112 |
-
2. Complete LinkedIn authentication
|
113 |
-
3. Handle callback in frontend
|
114 |
-
4. Process callback in backend
|
115 |
-
5. Verify database insertion
|
116 |
-
6. Confirm account appears in UI
|
117 |
-
|
118 |
-
#### 5.3 Database Testing
|
119 |
-
**Action**: Test database operations directly
|
120 |
-
**Verification**:
|
121 |
-
- Manual insertion of test data
|
122 |
-
- Verification of RLS policies
|
123 |
-
- Testing of error scenarios
|
124 |
-
|
125 |
-
## Implementation Timeline
|
126 |
-
|
127 |
-
### Week 1: Immediate Fixes
|
128 |
-
- [ ] Add enhanced logging to OAuth callback handler
|
129 |
-
- [ ] Verify database connection and permissions
|
130 |
-
- [ ] Test basic database insertion
|
131 |
-
- [ ] Fix any immediate issues found
|
132 |
-
|
133 |
-
### Week 2: Database & Security
|
134 |
-
- [ ] Verify table structure and constraints
|
135 |
-
- [ ] Check RLS policies and permissions
|
136 |
-
- [ ] Implement proper error handling
|
137 |
-
- [ ] Add input validation
|
138 |
-
|
139 |
-
### Week 3: Testing & Verification
|
140 |
-
- [ ] Create comprehensive unit tests
|
141 |
-
- [ ] Perform end-to-end integration testing
|
142 |
-
- [ ] Test error scenarios and edge cases
|
143 |
-
- [ ] Verify fix works in production environment
|
144 |
-
|
145 |
-
## Success Criteria
|
146 |
-
1. ✅ OAuth callback completes successfully
|
147 |
-
2. ✅ Account data is properly inserted into database
|
148 |
-
3. ✅ Account appears in user account list
|
149 |
-
4. ✅ Error handling provides clear feedback
|
150 |
-
5. ✅ All tests pass
|
151 |
-
|
152 |
-
## Monitoring & Maintenance
|
153 |
-
1. **Logging**: Monitor OAuth callback success/failure rates
|
154 |
-
2. **Database**: Regular backup and maintenance
|
155 |
-
3. **Security**: Regular review of RLS policies and permissions
|
156 |
-
4. **Performance**: Monitor database query performance
|
157 |
-
|
158 |
-
## Risk Assessment
|
159 |
-
- **High Risk**: Database connection issues
|
160 |
-
- **Medium Risk**: RLS policy conflicts
|
161 |
-
- **Low Risk**: Frontend callback handling
|
162 |
-
|
163 |
-
## Contingency Plans
|
164 |
-
1. **Database Issues**: Implement fallback logging and manual account creation
|
165 |
-
2. **OAuth Issues**: Provide alternative authentication methods
|
166 |
-
3. **Performance Issues**: Implement database connection pooling
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ACCOUNT_CREATION_FIX_SUMMARY.md
DELETED
@@ -1,184 +0,0 @@
|
|
1 |
-
# LinkedIn Account Creation Fix Summary
|
2 |
-
|
3 |
-
## Issue Analysis
|
4 |
-
|
5 |
-
The user reported that they were trying to add a LinkedIn account but couldn't see it in their database despite successful API calls in the logs. After analyzing the logs and code, I identified the root cause:
|
6 |
-
|
7 |
-
### Root Cause
|
8 |
-
The OAuth callback handler was trying to make a POST request to the same server (`/api/accounts/callback`) from within the callback handler, which was causing a 500 error. This prevented the OAuth data from being properly processed and stored in the database.
|
9 |
-
|
10 |
-
### Key Problems Identified
|
11 |
-
|
12 |
-
1. **Callback Handler Architecture Issue**: The backend callback handler was attempting to make an internal API call to complete the OAuth flow, which created a circular dependency and failed.
|
13 |
-
|
14 |
-
2. **Missing Session Management**: There was no proper session management to handle the OAuth data between the callback and the final account creation.
|
15 |
-
|
16 |
-
3. **Frontend-Backend Communication Gap**: The frontend was expecting direct URL parameter handling, but the backend was trying to process everything internally.
|
17 |
-
|
18 |
-
## Solution Implemented
|
19 |
-
|
20 |
-
### 1. Backend OAuth Callback Handler Redesign
|
21 |
-
|
22 |
-
**File**: `backend/app.py`
|
23 |
-
|
24 |
-
- **Simplified Callback Flow**: Removed the internal API call attempt and instead store OAuth data in Flask session
|
25 |
-
- **Proper Redirect**: Redirect back to the frontend with success/error indicators
|
26 |
-
- **Session Storage**: Store OAuth data (`code`, `state`, `social_network`) in Flask session for later retrieval
|
27 |
-
|
28 |
-
```python
|
29 |
-
# Store the OAuth data in the session for the frontend to pick up
|
30 |
-
from flask import session
|
31 |
-
session['oauth_data'] = {
|
32 |
-
'code': code,
|
33 |
-
'state': state,
|
34 |
-
'social_network': 'LinkedIn'
|
35 |
-
}
|
36 |
-
|
37 |
-
# Redirect to frontend with success indication
|
38 |
-
from flask import redirect
|
39 |
-
redirect_url = f"{request.host_url.rstrip('/')}?oauth_success=true&from=linkedin"
|
40 |
-
return redirect(redirect_url)
|
41 |
-
```
|
42 |
-
|
43 |
-
### 2. Frontend Callback Handler Update
|
44 |
-
|
45 |
-
**File**: `frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx`
|
46 |
-
|
47 |
-
- **Enhanced Parameter Handling**: Added support for `oauth_success` and `from` parameters
|
48 |
-
- **Session Data Retrieval**: Implemented proper session data retrieval via API endpoint
|
49 |
-
- **Improved Error Handling**: Added comprehensive error handling and logging
|
50 |
-
|
51 |
-
```javascript
|
52 |
-
// Check if we're coming from LinkedIn OAuth
|
53 |
-
if (from === 'linkedin') {
|
54 |
-
if (oauthSuccess === 'true') {
|
55 |
-
// Get OAuth data from backend session
|
56 |
-
const sessionResponse = await apiClient.get('/accounts/session-data');
|
57 |
-
if (sessionResponse.data.success && sessionResponse.data.oauth_data) {
|
58 |
-
const oauthData = sessionResponse.data.oauth_data;
|
59 |
-
// Process OAuth callback
|
60 |
-
}
|
61 |
-
}
|
62 |
-
}
|
63 |
-
```
|
64 |
-
|
65 |
-
### 3. Session Data API Endpoint
|
66 |
-
|
67 |
-
**File**: `backend/api/accounts.py`
|
68 |
-
|
69 |
-
- **New Endpoint**: Added `/api/accounts/session-data` endpoint to retrieve OAuth data from session
|
70 |
-
- **Proper Authentication**: Ensured JWT protection for the endpoint
|
71 |
-
- **Error Handling**: Added comprehensive error handling
|
72 |
-
|
73 |
-
```python
|
74 |
-
@accounts_bp.route('/session-data', methods=['GET'])
|
75 |
-
@jwt_required()
|
76 |
-
def get_session_data():
|
77 |
-
from flask import session
|
78 |
-
oauth_data = session.get('oauth_data', None)
|
79 |
-
|
80 |
-
if oauth_data:
|
81 |
-
return jsonify({
|
82 |
-
'success': True,
|
83 |
-
'oauth_data': oauth_data
|
84 |
-
}), 200
|
85 |
-
else:
|
86 |
-
return jsonify({
|
87 |
-
'success': False,
|
88 |
-
'message': 'No OAuth data found in session'
|
89 |
-
}), 404
|
90 |
-
```
|
91 |
-
|
92 |
-
### 4. Enhanced Logging and Debugging
|
93 |
-
|
94 |
-
**Files**: Multiple files updated with comprehensive logging
|
95 |
-
|
96 |
-
- **Backend Logging**: Added detailed logging throughout the OAuth flow
|
97 |
-
- **Frontend Logging**: Enhanced frontend callback handler with detailed debugging
|
98 |
-
- **Error Tracking**: Improved error tracking and reporting
|
99 |
-
|
100 |
-
## Technical Changes Summary
|
101 |
-
|
102 |
-
### Backend Changes
|
103 |
-
1. **OAuth Callback Handler**: Completely redesigned to use session-based approach
|
104 |
-
2. **Session Management**: Implemented proper Flask session management
|
105 |
-
3. **API Endpoint**: Added session data retrieval endpoint
|
106 |
-
4. **Error Handling**: Enhanced error handling and logging
|
107 |
-
|
108 |
-
### Frontend Changes
|
109 |
-
1. **Callback Handler**: Updated to handle new URL parameters and session data
|
110 |
-
2. **Error Handling**: Improved error handling and user feedback
|
111 |
-
3. **Logging**: Enhanced debugging capabilities
|
112 |
-
|
113 |
-
### Testing
|
114 |
-
1. **Test Script**: Created `backend/test_oauth_callback.py` for testing the callback flow
|
115 |
-
2. **Integration Testing**: Added comprehensive integration testing
|
116 |
-
|
117 |
-
## Expected Behavior After Fix
|
118 |
-
|
119 |
-
### Successful Account Creation Flow
|
120 |
-
1. User clicks "Connect LinkedIn Account"
|
121 |
-
2. User is redirected to LinkedIn for authentication
|
122 |
-
3. After successful authentication, LinkedIn redirects back to `/auth/callback`
|
123 |
-
4. Backend stores OAuth data in session and redirects to frontend with `?oauth_success=true&from=linkedin`
|
124 |
-
5. Frontend detects the callback parameters and retrieves OAuth data from backend
|
125 |
-
6. Frontend makes API call to `/api/accounts/callback` with OAuth data
|
126 |
-
7. Backend processes OAuth data, exchanges code for access token, and stores account in database
|
127 |
-
8. User sees success message and is redirected to sources page
|
128 |
-
|
129 |
-
### Error Handling
|
130 |
-
1. **Authentication Error**: If LinkedIn authentication fails, user is redirected back with error parameter
|
131 |
-
2. **Missing Parameters**: If required parameters are missing, appropriate error is shown
|
132 |
-
3. **Database Issues**: If database insertion fails, error is logged and user is informed
|
133 |
-
4. **Session Issues**: If session data is missing, user is prompted to try again
|
134 |
-
|
135 |
-
## Verification Steps
|
136 |
-
|
137 |
-
To verify the fix works:
|
138 |
-
|
139 |
-
1. **Start the backend server**: `python backend/app.py`
|
140 |
-
2. **Start the frontend server**: `npm run dev` (in frontend directory)
|
141 |
-
3. **Navigate to the application**: Open browser to the application URL
|
142 |
-
4. **Add LinkedIn Account**: Click "Connect LinkedIn Account" button
|
143 |
-
5. **Complete Authentication**: Follow through LinkedIn authentication process
|
144 |
-
6. **Verify Success**: Check that the account appears in the database and UI
|
145 |
-
|
146 |
-
### Testing with Test Script
|
147 |
-
```bash
|
148 |
-
cd backend
|
149 |
-
python test_oauth_callback.py
|
150 |
-
```
|
151 |
-
|
152 |
-
## Monitoring and Debugging
|
153 |
-
|
154 |
-
### Backend Logs
|
155 |
-
Look for these key log messages:
|
156 |
-
- `🔗 [OAuth] Direct callback handler triggered`
|
157 |
-
- `🔗 [OAuth] OAuth data stored in session`
|
158 |
-
- `🔗 [OAuth] Account linked successfully for user: [user_id]`
|
159 |
-
|
160 |
-
### Frontend Logs
|
161 |
-
Look for these key log messages:
|
162 |
-
- `🔗 [Frontend] LinkedIn callback handler started`
|
163 |
-
- `🔗 [Frontend] OAuth success detected, fetching session data...`
|
164 |
-
- `🔗 [Frontend] LinkedIn account linked successfully!`
|
165 |
-
|
166 |
-
## Database Verification
|
167 |
-
|
168 |
-
After successful account creation, verify the account exists in the `Social_network` table:
|
169 |
-
```sql
|
170 |
-
SELECT * FROM Social_network WHERE id_utilisateur = '[user_id]' AND social_network = 'LinkedIn';
|
171 |
-
```
|
172 |
-
|
173 |
-
## Conclusion
|
174 |
-
|
175 |
-
The fix addresses the core issue by implementing a proper session-based OAuth callback flow that avoids the circular dependency problem. The solution is more robust, maintainable, and provides better error handling and user feedback.
|
176 |
-
|
177 |
-
The key improvements are:
|
178 |
-
1. **Proper Session Management**: OAuth data is securely stored and retrieved
|
179 |
-
2. **Clean Architecture**: Separation of concerns between frontend and backend
|
180 |
-
3. **Better Error Handling**: Comprehensive error handling throughout the flow
|
181 |
-
4. **Enhanced Logging**: Detailed logging for debugging and monitoring
|
182 |
-
5. **User Experience**: Clear feedback and error messages for users
|
183 |
-
|
184 |
-
This fix should resolve the issue where accounts were not appearing in the database despite successful API calls.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ACCOUNT_CREATION_WORKFLOW.md
DELETED
@@ -1,150 +0,0 @@
|
|
1 |
-
# Account Creation Workflow Diagram
|
2 |
-
|
3 |
-
## Current Flow Analysis
|
4 |
-
|
5 |
-
```mermaid
|
6 |
-
graph TD
|
7 |
-
A[User Clicks "Add LinkedIn Account"] --> B[Frontend POST /api/accounts]
|
8 |
-
B --> C[Backend Initiate OAuth]
|
9 |
-
C --> D[Redirect to LinkedIn]
|
10 |
-
D --> E[User Authenticates with LinkedIn]
|
11 |
-
E --> F[LinkedIn Redirect to /auth/callback]
|
12 |
-
F --> G[Frontend LinkedInCallbackHandler]
|
13 |
-
G --> H[Frontend POST /accounts/callback]
|
14 |
-
H --> I[Backend handle_oauth_callback]
|
15 |
-
I --> J[Database Insert into Social_network]
|
16 |
-
J --> K[Return Success Response]
|
17 |
-
K --> L[Frontend Updates Account List]
|
18 |
-
L --> M[User Sees Account in UI]
|
19 |
-
|
20 |
-
style A fill:#e1f5fe
|
21 |
-
style M fill:#e8f5e8
|
22 |
-
style J fill:#ffebee
|
23 |
-
style K fill:#fff3e0
|
24 |
-
```
|
25 |
-
|
26 |
-
## Problem Identification
|
27 |
-
|
28 |
-
Based on the log analysis, the issue is occurring at step **J** - Database Insert into Social_network. The OAuth flow is working correctly (steps A-I complete successfully), but the database insertion is failing silently.
|
29 |
-
|
30 |
-
## Detailed Flow Breakdown
|
31 |
-
|
32 |
-
### Step 1: Account Initiation
|
33 |
-
- **Endpoint**: `POST /api/accounts`
|
34 |
-
- **File**: [`backend/api/accounts.py:69-124`](backend/api/accounts.py:69)
|
35 |
-
- **Action**: Initiates LinkedIn OAuth flow
|
36 |
-
- **Status**: ✅ Working (200 response in logs)
|
37 |
-
|
38 |
-
### Step 2: OAuth Redirect
|
39 |
-
- **Action**: Redirects user to LinkedIn for authentication
|
40 |
-
- **Status**: ✅ Working (successful LinkedIn auth in logs)
|
41 |
-
|
42 |
-
### Step 3: Callback Handling
|
43 |
-
- **Endpoint**: `GET /auth/callback`
|
44 |
-
- **File**: [`frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx`](frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx)
|
45 |
-
- **Action**: Processes LinkedIn callback
|
46 |
-
- **Status**: ✅ Working (successful callback in logs)
|
47 |
-
|
48 |
-
### Step 4: Backend Processing
|
49 |
-
- **Endpoint**: `POST /accounts/callback`
|
50 |
-
- **File**: [`backend/api/accounts.py:126-207`](backend/api/accounts.py:126)
|
51 |
-
- **Action**: Processes OAuth code and inserts into database
|
52 |
-
- **Status**: ❓ Unknown (no logs for this endpoint)
|
53 |
-
|
54 |
-
### Step 5: Database Insertion
|
55 |
-
- **Table**: `Social_network`
|
56 |
-
- **Action**: Insert account data
|
57 |
-
- **Status**: ❓ Unknown (no evidence of success/failure)
|
58 |
-
|
59 |
-
## Key Issues Identified
|
60 |
-
|
61 |
-
### 1. Missing Logging
|
62 |
-
The OAuth callback handler lacks sufficient logging to track:
|
63 |
-
- Received parameters
|
64 |
-
- Database connection status
|
65 |
-
- Insertion attempts and results
|
66 |
-
- Error conditions
|
67 |
-
|
68 |
-
### 2. Silent Failures
|
69 |
-
The error handling may be suppressing exceptions and returning 200 even when failures occur.
|
70 |
-
|
71 |
-
### 3. Database Verification
|
72 |
-
No verification that the database insertion was successful before returning a success response.
|
73 |
-
|
74 |
-
## Recommended Workflow Enhancements
|
75 |
-
|
76 |
-
### Enhanced Logging Flow
|
77 |
-
```mermaid
|
78 |
-
graph TD
|
79 |
-
A[OAuth Callback Received] --> B[Log Received Data]
|
80 |
-
B --> C[Validate Parameters]
|
81 |
-
C --> D[Log Validation Results]
|
82 |
-
D --> E[Exchange Code for Token]
|
83 |
-
E --> F[Log Token Exchange]
|
84 |
-
F --> G[Get User Info]
|
85 |
-
G --> H[Log User Info]
|
86 |
-
H --> I[Database Insertion]
|
87 |
-
I --> J[Log Insertion Result]
|
88 |
-
J --> K{Success?}
|
89 |
-
K -->|Yes| L[Return Success]
|
90 |
-
K -->|No| M[Return Error]
|
91 |
-
M --> N[Log Error Details]
|
92 |
-
```
|
93 |
-
|
94 |
-
### Error Handling Flow
|
95 |
-
```mermaid
|
96 |
-
graph TD
|
97 |
-
A[Error Occurs] --> B[Log Error]
|
98 |
-
B --> C[Determine Error Type]
|
99 |
-
C --> D{Database Error?}
|
100 |
-
D -->|Yes| E[Log Database Details]
|
101 |
-
D -->|No| F[Log General Error]
|
102 |
-
E --> G[Return 500 Error]
|
103 |
-
F --> G
|
104 |
-
G --> H[Add CORS Headers]
|
105 |
-
```
|
106 |
-
|
107 |
-
## Data Flow Analysis
|
108 |
-
|
109 |
-
### OAuth Data Flow
|
110 |
-
```
|
111 |
-
LinkedIn → Authorization Code → Backend → Access Token → User Info → Database
|
112 |
-
```
|
113 |
-
|
114 |
-
### Database Schema Requirements
|
115 |
-
```sql
|
116 |
-
CREATE TABLE Social_network (
|
117 |
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
118 |
-
social_network TEXT NOT NULL,
|
119 |
-
account_name TEXT NOT NULL,
|
120 |
-
id_utilisateur TEXT NOT NULL,
|
121 |
-
token TEXT,
|
122 |
-
sub TEXT,
|
123 |
-
given_name TEXT,
|
124 |
-
family_name TEXT,
|
125 |
-
picture TEXT,
|
126 |
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
127 |
-
);
|
128 |
-
|
129 |
-
-- RLS Policy
|
130 |
-
CREATE POLICY "Users can manage their own accounts"
|
131 |
-
ON Social_network
|
132 |
-
FOR ALL
|
133 |
-
USING (auth.uid()::text = id_utilisateur);
|
134 |
-
```
|
135 |
-
|
136 |
-
## Next Steps
|
137 |
-
|
138 |
-
1. **Add comprehensive logging** to track the complete OAuth flow
|
139 |
-
2. **Verify database connection** and permissions
|
140 |
-
3. **Test database insertion** with sample data
|
141 |
-
4. **Implement proper error handling** with detailed feedback
|
142 |
-
5. **Create monitoring** for account creation success/failure rates
|
143 |
-
|
144 |
-
## Success Metrics
|
145 |
-
|
146 |
-
- ✅ OAuth callback receives and processes data correctly
|
147 |
-
- ✅ Database insertion succeeds consistently
|
148 |
-
- ✅ Error handling provides clear feedback
|
149 |
-
- ✅ Accounts appear in user interface immediately
|
150 |
-
- ✅ Logging provides complete visibility into the process
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CELERY_SCHEDULING_SETUP.md
DELETED
@@ -1,340 +0,0 @@
|
|
1 |
-
# Celery Scheduling Setup Guide
|
2 |
-
|
3 |
-
This guide explains how to set up and use the Celery scheduling system with your Lin application.
|
4 |
-
|
5 |
-
## Overview
|
6 |
-
|
7 |
-
The updated `start_app.py` now automatically starts both the Flask application and Celery components (worker and beat scheduler) when you run the application. This ensures that your scheduled tasks will execute properly.
|
8 |
-
|
9 |
-
## Prerequisites
|
10 |
-
|
11 |
-
### 1. Redis Server
|
12 |
-
Celery requires Redis as a message broker. Make sure Redis is installed and running:
|
13 |
-
|
14 |
-
**Windows:**
|
15 |
-
```bash
|
16 |
-
# Install Redis (if not installed)
|
17 |
-
# Download from https://github.com/microsoftarchive/redis/releases
|
18 |
-
|
19 |
-
# Start Redis server
|
20 |
-
redis-server
|
21 |
-
```
|
22 |
-
|
23 |
-
**Linux/Mac:**
|
24 |
-
```bash
|
25 |
-
# Install Redis
|
26 |
-
sudo apt-get install redis-server # Ubuntu/Debian
|
27 |
-
brew install redis # macOS
|
28 |
-
|
29 |
-
# Start Redis
|
30 |
-
sudo systemctl start redis
|
31 |
-
sudo systemctl enable redis
|
32 |
-
```
|
33 |
-
|
34 |
-
### 2. Hugging Face Spaces / Production Deployment
|
35 |
-
For Hugging Face Spaces or production deployments where you can't run Redis directly:
|
36 |
-
|
37 |
-
**Option A: Use Redis Cloud (Recommended)**
|
38 |
-
1. Create a free Redis Cloud account at https://redislabs.com/try-free/
|
39 |
-
2. Create a Redis database (free tier available)
|
40 |
-
3. Update your `.env` file:
|
41 |
-
```env
|
42 |
-
CELERY_BROKER_URL="redis://your-redis-host:port/0"
|
43 |
-
CELERY_RESULT_BACKEND="redis://your-redis-host:port/0"
|
44 |
-
```
|
45 |
-
|
46 |
-
**Option B: Use Docker Compose**
|
47 |
-
```yaml
|
48 |
-
# docker-compose.yml
|
49 |
-
version: '3.8'
|
50 |
-
services:
|
51 |
-
redis:
|
52 |
-
image: redis:7-alpine
|
53 |
-
ports:
|
54 |
-
- "6379:6379"
|
55 |
-
volumes:
|
56 |
-
- redis_data:/data
|
57 |
-
command: redis-server --appendonly yes
|
58 |
-
|
59 |
-
volumes:
|
60 |
-
redis_data:
|
61 |
-
```
|
62 |
-
|
63 |
-
**Option C: Skip Celery (Basic Mode)**
|
64 |
-
If Redis is not available, the Flask app will start without Celery functionality. Schedules will be saved but won't execute automatically.
|
65 |
-
|
66 |
-
### 2. Python Dependencies
|
67 |
-
Install the required packages:
|
68 |
-
```bash
|
69 |
-
pip install -r backend/requirements.txt
|
70 |
-
```
|
71 |
-
|
72 |
-
## Starting the Application
|
73 |
-
|
74 |
-
### Using start_app.py (Recommended)
|
75 |
-
```bash
|
76 |
-
python start_app.py
|
77 |
-
```
|
78 |
-
|
79 |
-
This will:
|
80 |
-
1. Check Redis connection
|
81 |
-
2. Start Celery worker in the background
|
82 |
-
3. Start Celery beat scheduler in the background
|
83 |
-
4. Start the Flask application
|
84 |
-
|
85 |
-
### Using Backend Scripts (Alternative)
|
86 |
-
```bash
|
87 |
-
# Start both worker and beat
|
88 |
-
cd backend
|
89 |
-
python start_celery.py all
|
90 |
-
|
91 |
-
# Or start individually
|
92 |
-
python start_celery.py worker # Start Celery worker
|
93 |
-
python start_celery.py beat # Start Celery beat scheduler
|
94 |
-
```
|
95 |
-
|
96 |
-
## Configuration
|
97 |
-
|
98 |
-
### Environment Variables
|
99 |
-
Make sure these are set in your `.env` file:
|
100 |
-
|
101 |
-
```env
|
102 |
-
# Supabase configuration
|
103 |
-
SUPABASE_URL="your_supabase_url"
|
104 |
-
SUPABASE_KEY="your_supabase_key"
|
105 |
-
|
106 |
-
# Redis configuration (if not using defaults)
|
107 |
-
CELERY_BROKER_URL="redis://localhost:6379/0"
|
108 |
-
CELERY_RESULT_BACKEND="redis://localhost:6379/0"
|
109 |
-
|
110 |
-
# Scheduler configuration
|
111 |
-
SCHEDULER_ENABLED=True
|
112 |
-
```
|
113 |
-
|
114 |
-
### Celery Configuration
|
115 |
-
The unified configuration is in `backend/celery_config.py`:
|
116 |
-
|
117 |
-
```python
|
118 |
-
celery_app.conf.beat_schedule = {
|
119 |
-
'load-schedules': {
|
120 |
-
'task': 'backend.celery_tasks.schedule_loader.load_schedules_task',
|
121 |
-
'schedule': crontab(minute='*/5'), # Every 5 minutes
|
122 |
-
},
|
123 |
-
}
|
124 |
-
```
|
125 |
-
|
126 |
-
## How Scheduling Works
|
127 |
-
|
128 |
-
### 1. Schedule Loading
|
129 |
-
- **Immediate Updates**: When you create or delete a schedule via the API, Celery Beat is updated immediately
|
130 |
-
- **Periodic Updates**: Celery Beat also runs every 5 minutes as a backup
|
131 |
-
- Executes `load_schedules_task`
|
132 |
-
- Fetches schedules from Supabase database
|
133 |
-
- Creates individual periodic tasks for each schedule
|
134 |
-
|
135 |
-
### 2. Task Execution
|
136 |
-
- **Content Generation**: Runs 5 minutes before scheduled time
|
137 |
-
- **Post Publishing**: Runs at the scheduled time
|
138 |
-
- Tasks are queued in appropriate queues (content, publish)
|
139 |
-
|
140 |
-
### 3. Database Integration
|
141 |
-
- Uses Supabase for schedule storage
|
142 |
-
- Automatically creates tasks based on schedule data
|
143 |
-
- Handles social network authentication
|
144 |
-
|
145 |
-
## Monitoring and Debugging
|
146 |
-
|
147 |
-
### Checking Celery Status
|
148 |
-
```bash
|
149 |
-
# Check worker status
|
150 |
-
celery -A celery_config inspect stats
|
151 |
-
|
152 |
-
# Check scheduled tasks
|
153 |
-
celery -A celery_config inspect scheduled
|
154 |
-
|
155 |
-
# Check active tasks
|
156 |
-
celery -A celery_config inspect active
|
157 |
-
```
|
158 |
-
|
159 |
-
### Viewing Logs
|
160 |
-
- **Flask Application**: Check console output
|
161 |
-
- **Celery Worker**: Look for worker process logs
|
162 |
-
- **Celery Beat**: Look for beat process logs
|
163 |
-
|
164 |
-
### Common Issues
|
165 |
-
|
166 |
-
**1. Redis Connection Failed**
|
167 |
-
```
|
168 |
-
Error: Error 111 connecting to localhost:6379. Connection refused
|
169 |
-
|
170 |
-
Solutions:
|
171 |
-
1. Start Redis server locally (development):
|
172 |
-
Windows: redis-server
|
173 |
-
Linux/Mac: sudo systemctl start redis
|
174 |
-
|
175 |
-
2. Use Redis Cloud (production/Hugging Face):
|
176 |
-
- Create free Redis Cloud account
|
177 |
-
- Update .env with Redis Cloud URL
|
178 |
-
- Set CELERY_BROKER_URL and CELERY_RESULT_BACKEND
|
179 |
-
|
180 |
-
3. Use Docker Compose:
|
181 |
-
version: '3.8'
|
182 |
-
services:
|
183 |
-
redis:
|
184 |
-
image: redis:7-alpine
|
185 |
-
ports: ["6379:6379"]
|
186 |
-
volumes: [redis_data:/data]
|
187 |
-
volumes: redis_data:
|
188 |
-
|
189 |
-
4. Skip Celery (basic mode):
|
190 |
-
- App will start without scheduling functionality
|
191 |
-
- Schedules saved but won't execute automatically
|
192 |
-
```
|
193 |
-
|
194 |
-
**2. Tasks Not Executing**
|
195 |
-
```bash
|
196 |
-
# Check if Celery worker is running
|
197 |
-
celery -A celery_config inspect ping
|
198 |
-
|
199 |
-
# Check if beat scheduler is running
|
200 |
-
ps aux | grep celery
|
201 |
-
```
|
202 |
-
|
203 |
-
**3. Schedule Not Loading**
|
204 |
-
- Check Supabase database connection
|
205 |
-
- Verify schedule data in database
|
206 |
-
- Check task registration in Celery
|
207 |
-
|
208 |
-
## Testing the Scheduling System
|
209 |
-
|
210 |
-
### Manual Testing
|
211 |
-
```python
|
212 |
-
# Test schedule loading task
|
213 |
-
from backend.celery_tasks.schedule_loader import load_schedules_task
|
214 |
-
result = load_schedules_task()
|
215 |
-
print(result)
|
216 |
-
```
|
217 |
-
|
218 |
-
### API Testing (Recommended)
|
219 |
-
1. **Create a schedule via the API**:
|
220 |
-
```bash
|
221 |
-
curl -X POST http://localhost:5000/api/schedules/ \
|
222 |
-
-H "Content-Type: application/json" \
|
223 |
-
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
224 |
-
-d '{
|
225 |
-
"social_network": "1",
|
226 |
-
"schedule_time": "09:00",
|
227 |
-
"days": ["Monday", "Wednesday", "Friday"]
|
228 |
-
}'
|
229 |
-
```
|
230 |
-
|
231 |
-
2. **Check the response**: You should see a `celery_update_task_id` field indicating the scheduler was updated immediately
|
232 |
-
|
233 |
-
3. **Verify in Celery**: Check if the individual tasks were created:
|
234 |
-
```bash
|
235 |
-
celery -A celery_config inspect scheduled
|
236 |
-
```
|
237 |
-
|
238 |
-
### Database Testing
|
239 |
-
1. Add a schedule directly in the Supabase database
|
240 |
-
2. Wait 5 minutes for the loader task to run (or trigger via API)
|
241 |
-
3. Check if individual tasks were created
|
242 |
-
4. Verify task execution times
|
243 |
-
|
244 |
-
## Production Deployment
|
245 |
-
|
246 |
-
### Using Docker (Recommended for Hugging Face Spaces)
|
247 |
-
```bash
|
248 |
-
# Build the Docker image
|
249 |
-
docker build -t lin-app .
|
250 |
-
|
251 |
-
# Run the container
|
252 |
-
docker run -p 7860:7860 lin-app
|
253 |
-
|
254 |
-
# For Hugging Face Spaces deployment:
|
255 |
-
# 1. Update your Dockerfile (already done above)
|
256 |
-
# 2. Push to Hugging Face Spaces
|
257 |
-
# 3. The container will automatically start Redis + your app
|
258 |
-
```
|
259 |
-
|
260 |
-
### Using Docker Compose (Local Development)
|
261 |
-
```yaml
|
262 |
-
# docker-compose.yml
|
263 |
-
version: '3.8'
|
264 |
-
services:
|
265 |
-
redis:
|
266 |
-
image: redis:7-alpine
|
267 |
-
ports: ["6379:6379"]
|
268 |
-
volumes: [redis_data:/data]
|
269 |
-
command: redis-server --appendonly yes
|
270 |
-
|
271 |
-
app:
|
272 |
-
build: .
|
273 |
-
ports: ["7860:7860"]
|
274 |
-
depends_on: [redis]
|
275 |
-
environment:
|
276 |
-
- REDIS_URL=redis://redis:6379/0
|
277 |
-
volumes: [./:/app]
|
278 |
-
|
279 |
-
volumes: redis_data:
|
280 |
-
```
|
281 |
-
|
282 |
-
```bash
|
283 |
-
# Start all services
|
284 |
-
docker-compose up -d
|
285 |
-
|
286 |
-
# Check logs
|
287 |
-
docker-compose logs -f
|
288 |
-
```
|
289 |
-
|
290 |
-
### Using Docker
|
291 |
-
```bash
|
292 |
-
# Build and start all services
|
293 |
-
docker-compose up -d
|
294 |
-
|
295 |
-
# Check logs
|
296 |
-
docker-compose logs -f
|
297 |
-
```
|
298 |
-
|
299 |
-
### Using Supervisor (Linux)
|
300 |
-
Create `/etc/supervisor/conf.d/lin.conf`:
|
301 |
-
```ini
|
302 |
-
[program:lin_worker]
|
303 |
-
command=python start_app.py
|
304 |
-
directory=/path/to/lin
|
305 |
-
autostart=true
|
306 |
-
autorestart=true
|
307 |
-
user=www-data
|
308 |
-
environment=PATH="/path/to/venv/bin"
|
309 |
-
|
310 |
-
[program:lin_beat]
|
311 |
-
command=python -m celery -A celery_config beat
|
312 |
-
directory=/path/to/lin
|
313 |
-
autostart=true
|
314 |
-
autorestart=true
|
315 |
-
user=www-data
|
316 |
-
environment=PATH="/path/to/venv/bin"
|
317 |
-
```
|
318 |
-
|
319 |
-
## Troubleshooting Checklist
|
320 |
-
|
321 |
-
1. ✅ Redis server is running
|
322 |
-
2. ✅ All Python dependencies are installed
|
323 |
-
3. ✅ Environment variables are set correctly
|
324 |
-
4. ✅ Supabase database connection works
|
325 |
-
5. ✅ Celery worker is running
|
326 |
-
6. ✅ Celery beat scheduler is running
|
327 |
-
7. ✅ Schedule data exists in database
|
328 |
-
8. ✅ Tasks are properly registered
|
329 |
-
9. ✅ Task execution permissions are correct
|
330 |
-
|
331 |
-
## Support
|
332 |
-
|
333 |
-
If you encounter issues:
|
334 |
-
1. Check this guide first
|
335 |
-
2. Review the logs for error messages
|
336 |
-
3. Verify all prerequisites are met
|
337 |
-
4. Test components individually
|
338 |
-
5. Check the Celery documentation
|
339 |
-
|
340 |
-
For additional help, refer to the Celery documentation at: https://docs.celeryq.dev/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEPLOYMENT_VERIFICATION_CHECKLIST.md
DELETED
@@ -1,165 +0,0 @@
|
|
1 |
-
# Deployment Verification Checklist
|
2 |
-
|
3 |
-
## Authentication Fix for Hugging Face Spaces
|
4 |
-
|
5 |
-
This checklist will help you verify that the authentication fixes work correctly in your Hugging Face Space deployment.
|
6 |
-
|
7 |
-
### ✅ Pre-Deployment Checks
|
8 |
-
|
9 |
-
#### 1. Frontend Configuration
|
10 |
-
- [ ] `.env.production` file has correct API URL: `https://zelyanoth-lin-cbfcff2.hf.space/api`
|
11 |
-
- [ ] `VITE_NODE_ENV=production` is set in `.env.production`
|
12 |
-
- [ ] Frontend has been built with `npm run build`
|
13 |
-
- [ ] `dist/` folder exists and contains built files
|
14 |
-
|
15 |
-
#### 2. Backend Configuration
|
16 |
-
- [ ] `backend/app.py` imports `request` from Flask
|
17 |
-
- [ ] CORS origins include `https://zelyanoth-lin-cbfcff2.hf.space`
|
18 |
-
- [ ] Cookie service uses `sameSite: 'Lax'` for production
|
19 |
-
- [ ] JWT secret key is properly configured
|
20 |
-
|
21 |
-
#### 3. Cookie Security Settings
|
22 |
-
- [ ] Production cookies use `sameSite: 'Lax'` (not 'Strict')
|
23 |
-
- [ ] Production cookies use `secure: true`
|
24 |
-
- [ ] All cookies have `httpOnly: true`
|
25 |
-
- [ ] CORS allows credentials (`supports_credentials: true`)
|
26 |
-
|
27 |
-
### ✅ Deployment Steps
|
28 |
-
|
29 |
-
#### 1. Build Frontend
|
30 |
-
```bash
|
31 |
-
cd frontend
|
32 |
-
npm run build
|
33 |
-
cd ..
|
34 |
-
```
|
35 |
-
|
36 |
-
#### 2. Commit Changes
|
37 |
-
```bash
|
38 |
-
git add .
|
39 |
-
git commit -m "fix: authentication fixes for Hugging Face Spaces deployment"
|
40 |
-
git push origin main
|
41 |
-
```
|
42 |
-
|
43 |
-
#### 3. Monitor Hugging Face Build
|
44 |
-
- [ ] Check build logs in Hugging Face Space dashboard
|
45 |
-
- [ ] Verify no errors during build process
|
46 |
-
- [ ] Confirm deployment completes successfully
|
47 |
-
|
48 |
-
### ✅ Post-Deployment Testing
|
49 |
-
|
50 |
-
#### 1. Basic Functionality Tests
|
51 |
-
- [ ] Application loads at `https://zelyanoth-lin-cbfcff2.hf.space`
|
52 |
-
- [ ] Health check endpoint works: `https://zelyanoth-lin-cbfcff2.hf.space/health`
|
53 |
-
- [ ] API health check works: `https://zelyanoth-lin-cbfcff2.hf.space/api/health`
|
54 |
-
|
55 |
-
#### 2. Authentication Flow Tests
|
56 |
-
- [ ] **Login Page**: Access `/login` page
|
57 |
-
- [ ] **Login Attempt**: Try to login with valid credentials
|
58 |
-
- [ ] **Login Success**: Verify successful login redirects to dashboard
|
59 |
-
- [ ] **Cookie Storage**: Check that cookies are set (use browser dev tools)
|
60 |
-
- [ ] **Page Reload**: Refresh the page while logged in
|
61 |
-
- [ ] **Session Persistence**: Verify you remain logged in after reload
|
62 |
-
- [ ] **Protected Routes**: Access `/dashboard`, `/accounts`, etc. while logged in
|
63 |
-
- [ ] **Logout**: Test logout functionality
|
64 |
-
- [ ] **Post-Logout**: Verify redirect to login page after logout
|
65 |
-
|
66 |
-
#### 3. Cookie Security Verification
|
67 |
-
- [ ] **Cookie Attributes**: Check browser cookies for:
|
68 |
-
- `SameSite=Lax` (production setting)
|
69 |
-
- `Secure` flag (for HTTPS)
|
70 |
-
- `HttpOnly` flag (prevents JavaScript access)
|
71 |
-
- [ ] **Cross-Origin Requests**: Verify CORS headers are present in API responses
|
72 |
-
- [ ] **Token Validation**: JWT tokens are properly validated on server side
|
73 |
-
|
74 |
-
#### 4. Error Handling Tests
|
75 |
-
- [ ] **Invalid Credentials**: Try login with wrong password
|
76 |
-
- [ ] **Expired Token**: Wait for token to expire (1 hour) and test reload
|
77 |
-
- [ ] **Network Issues**: Test with network disabled then reconnected
|
78 |
-
- [ ] **Browser Cache**: Clear browser cache and test authentication
|
79 |
-
|
80 |
-
#### 5. Browser Compatibility
|
81 |
-
- [ ] **Chrome**: Test all functionality
|
82 |
-
- [ ] **Firefox**: Test all functionality
|
83 |
-
- [ ] **Safari**: Test all functionality
|
84 |
-
- [ ] **Mobile Chrome**: Test on mobile device
|
85 |
-
- [ ] **Mobile Safari**: Test on mobile device
|
86 |
-
|
87 |
-
### ✅ Monitoring and Logging
|
88 |
-
|
89 |
-
#### 1. Browser Console
|
90 |
-
- [ ] No JavaScript errors on page load
|
91 |
-
- [ ] API requests show correct status codes
|
92 |
-
- [ ] Authentication requests show proper headers
|
93 |
-
|
94 |
-
#### 2. Network Tab
|
95 |
-
- [ ] API requests include Authorization header when logged in
|
96 |
-
- [ ] CORS requests show correct `Access-Control-Allow-*` headers
|
97 |
-
- [ ] No failed authentication requests
|
98 |
-
|
99 |
-
#### 3. Server Logs (Hugging Face Dashboard)
|
100 |
-
- [ ] No Flask application errors
|
101 |
-
- [ ] Successful health checks
|
102 |
-
- [ ] Authentication requests logged properly
|
103 |
-
- [ ] CORS headers applied correctly
|
104 |
-
|
105 |
-
### ✅ Performance Tests
|
106 |
-
|
107 |
-
#### 1. Load Time
|
108 |
-
- [ ] Page loads within 3 seconds
|
109 |
-
- [ ] API responses under 1 second
|
110 |
-
- [ ] Login process completes within 2 seconds
|
111 |
-
|
112 |
-
#### 2. Resource Usage
|
113 |
-
- [ ] Memory usage is reasonable
|
114 |
-
- [ ] No memory leaks detected
|
115 |
-
- [ ] CPU usage normal for traffic level
|
116 |
-
|
117 |
-
### ✅ Security Verification
|
118 |
-
|
119 |
-
#### 1. Cookie Security
|
120 |
-
- [ ] No sensitive data in localStorage (should use cookies only)
|
121 |
-
- [ ] CSRF protection working (via SameSite policy)
|
122 |
-
- [ ] XSS protection (HttpOnly cookies)
|
123 |
-
|
124 |
-
#### 2. API Security
|
125 |
-
- [ ] Unauthenticated requests to protected routes return 401
|
126 |
-
- [ ] JWT tokens properly validated
|
127 |
-
- [ ] No exposed sensitive data in API responses
|
128 |
-
|
129 |
-
### 🚨 Troubleshooting Guide
|
130 |
-
|
131 |
-
#### Common Issues and Solutions
|
132 |
-
|
133 |
-
**Issue: "NameError: name 'request' is not defined"**
|
134 |
-
- ✅ Fixed: Added `from flask import request` to `backend/app.py`
|
135 |
-
|
136 |
-
**Issue: Authentication fails after page reload**
|
137 |
-
- ✅ Fixed: Changed cookie `sameSite` from 'Strict' to 'Lax' for production
|
138 |
-
- ✅ Fixed: Updated API client to use production URL
|
139 |
-
|
140 |
-
**Issue: CORS errors in browser console**
|
141 |
-
- ✅ Fixed: Added Hugging Face Space URL to CORS origins
|
142 |
-
- ✅ Fixed: Ensured CORS headers include necessary fields
|
143 |
-
|
144 |
-
**Issue: Cookies not being set**
|
145 |
-
- ✅ Verify: `secure` flag matches HTTPS environment
|
146 |
-
- ✅ Verify: `sameSite` policy is appropriate for deployment
|
147 |
-
- ✅ Verify: CORS allows credentials
|
148 |
-
|
149 |
-
### 📝 Final Verification
|
150 |
-
|
151 |
-
#### Success Criteria
|
152 |
-
- [ ] User can login successfully
|
153 |
-
- [ ] User remains logged in after page reload
|
154 |
-
- [ ] Protected routes are accessible only when authenticated
|
155 |
-
- [ ] Logout functionality works correctly
|
156 |
-
- [ ] No console errors or warnings
|
157 |
-
- [ ] All security headers are present
|
158 |
-
- [ ] Application works across different browsers
|
159 |
-
|
160 |
-
#### Deployment Complete When:
|
161 |
-
All checkboxes above are marked as complete ✅
|
162 |
-
|
163 |
-
---
|
164 |
-
|
165 |
-
**Note**: If any test fails, refer to the troubleshooting guide above and ensure all fixes have been applied before redeploying.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FINAL_APSCHEDULER_MIGRATION_SUMMARY.md
DELETED
@@ -1,60 +0,0 @@
|
|
1 |
-
# APScheduler Migration - Implementation Complete
|
2 |
-
|
3 |
-
## Summary
|
4 |
-
|
5 |
-
We have successfully migrated the Lin application from Celery to APScheduler for task scheduling. This migration simplifies the architecture, reduces dependencies, and makes the application easier to deploy and maintain.
|
6 |
-
|
7 |
-
## Key Changes
|
8 |
-
|
9 |
-
1. **Removed Dependencies**:
|
10 |
-
- Removed `celery` and `redis` from requirements.txt
|
11 |
-
- Kept `apscheduler` as the scheduling library
|
12 |
-
|
13 |
-
2. **New Scheduler Service**:
|
14 |
-
- Created `backend/scheduler/apscheduler_service.py` with full APScheduler implementation
|
15 |
-
- Implemented content generation and post publishing tasks
|
16 |
-
- Added immediate schedule loading on app startup
|
17 |
-
- Added periodic schedule reloading every 5 minutes
|
18 |
-
|
19 |
-
3. **Updated Flask Application**:
|
20 |
-
- Modified `backend/app.py` to initialize APScheduler
|
21 |
-
- Added scheduler initialization when `SCHEDULER_ENABLED` is True
|
22 |
-
|
23 |
-
4. **Updated API Endpoints**:
|
24 |
-
- Modified `backend/api/schedules.py` to trigger APScheduler updates
|
25 |
-
- Removed all references to Celery task IDs in responses
|
26 |
-
|
27 |
-
5. **Simplified Startup**:
|
28 |
-
- Updated `start_app.py` to remove Celery initialization
|
29 |
-
- Application now starts with just Flask and APScheduler
|
30 |
-
|
31 |
-
6. **Removed Files**:
|
32 |
-
- Removed all Celery-related files and directories
|
33 |
-
- Cleaned up the codebase from legacy components
|
34 |
-
|
35 |
-
7. **Documentation**:
|
36 |
-
- Created comprehensive documentation for the new APScheduler setup
|
37 |
-
- Added migration guide and implementation summary
|
38 |
-
|
39 |
-
## Benefits Achieved
|
40 |
-
|
41 |
-
1. **Simplified Architecture**: Single process deployment with no external dependencies
|
42 |
-
2. **Easier Setup**: No need to install and configure Redis
|
43 |
-
3. **Reduced Complexity**: Fewer moving parts to manage
|
44 |
-
4. **Better Resource Usage**: Lower memory and CPU footprint
|
45 |
-
5. **Easier Debugging**: All logs in one place
|
46 |
-
6. **Simplified Deployment**: No need for separate worker processes
|
47 |
-
|
48 |
-
## Next Steps
|
49 |
-
|
50 |
-
1. Test the application thoroughly to ensure all scheduling functionality works correctly
|
51 |
-
2. Monitor logs for any issues with task execution
|
52 |
-
3. Consider adding more comprehensive error handling and monitoring
|
53 |
-
4. Update any remaining documentation references
|
54 |
-
|
55 |
-
## Files to Review
|
56 |
-
|
57 |
-
- `APSCHEDULER_SETUP.md` - Complete setup and usage guide
|
58 |
-
- `MIGRATION_TO_APSCHEDULER.md` - Migration guide from Celery
|
59 |
-
- `APSCHEDULER_IMPLEMENTATION_SUMMARY.md` - Technical implementation summary
|
60 |
-
- `backend/scheduler/apscheduler_service.py` - Main scheduler implementation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FINAL_DOCUMENTATION.md
DELETED
@@ -1,692 +0,0 @@
|
|
1 |
-
# Lin React Clone - Final Documentation
|
2 |
-
|
3 |
-
## Project Overview
|
4 |
-
|
5 |
-
This documentation provides a comprehensive overview of the Lin React Clone project, which is a modern reimplementation of the original Taipy-based Lin application using a React frontend with a Flask API backend. The project maintains all core functionality while improving the architecture for better maintainability and scalability.
|
6 |
-
|
7 |
-
## Table of Contents
|
8 |
-
|
9 |
-
1. [Architecture Overview](#architecture-overview)
|
10 |
-
2. [Backend Implementation](#backend-implementation)
|
11 |
-
3. [Frontend Implementation](#frontend-implementation)
|
12 |
-
4. [API Documentation](#api-documentation)
|
13 |
-
5. [Deployment Guide](#deployment-guide)
|
14 |
-
6. [Testing Strategy](#testing-strategy)
|
15 |
-
7. [Future Enhancements](#future-enhancements)
|
16 |
-
|
17 |
-
## Architecture Overview
|
18 |
-
|
19 |
-
### System Components
|
20 |
-
|
21 |
-
The Lin React Clone consists of two main components:
|
22 |
-
|
23 |
-
1. **Frontend (React)**
|
24 |
-
- User interface built with React
|
25 |
-
- State management with Redux Toolkit
|
26 |
-
- Responsive design for all device sizes
|
27 |
-
- Component-based architecture
|
28 |
-
|
29 |
-
2. **Backend (Flask API)**
|
30 |
-
- RESTful API built with Flask
|
31 |
-
- Database integration with Supabase
|
32 |
-
- Task scheduling with APScheduler
|
33 |
-
- External API integrations (LinkedIn, Hugging Face)
|
34 |
-
|
35 |
-
### Data Flow
|
36 |
-
|
37 |
-
```
|
38 |
-
[React Frontend] ↔ [Flask API] ↔ [Supabase Database]
|
39 |
-
↓
|
40 |
-
[External APIs: LinkedIn, Hugging Face]
|
41 |
-
↓
|
42 |
-
[APScheduler Tasks]
|
43 |
-
```
|
44 |
-
|
45 |
-
### Technology Stack
|
46 |
-
|
47 |
-
#### Backend
|
48 |
-
- Flask (Python web framework)
|
49 |
-
- Supabase (Database and authentication)
|
50 |
-
- APScheduler (Task scheduling)
|
51 |
-
- requests (HTTP library)
|
52 |
-
- requests-oauthlib (OAuth support)
|
53 |
-
- gradio-client (Hugging Face API)
|
54 |
-
- Flask-JWT-Extended (JWT token management)
|
55 |
-
|
56 |
-
#### Frontend
|
57 |
-
- React (JavaScript library)
|
58 |
-
- Redux Toolkit (State management)
|
59 |
-
- React Router (Routing)
|
60 |
-
- Axios (HTTP client)
|
61 |
-
- Material-UI (UI components)
|
62 |
-
|
63 |
-
## Backend Implementation
|
64 |
-
|
65 |
-
### Project Structure
|
66 |
-
|
67 |
-
```
|
68 |
-
backend/
|
69 |
-
├── app.py # Flask application entry point
|
70 |
-
├── config.py # Configuration settings
|
71 |
-
├── requirements.txt # Python dependencies
|
72 |
-
├── .env.example # Environment variables example
|
73 |
-
├── models/ # Data models
|
74 |
-
│ ├── user.py # User model
|
75 |
-
│ ├── social_account.py # Social media account model
|
76 |
-
│ ├── source.py # RSS source model
|
77 |
-
│ ├── post.py # Post content model
|
78 |
-
│ └── schedule.py # Scheduling model
|
79 |
-
├── api/ # API endpoints
|
80 |
-
│ ├── auth.py # Authentication endpoints
|
81 |
-
│ ├── sources.py # Source management endpoints
|
82 |
-
│ ├── accounts.py # Social account endpoints
|
83 |
-
│ ├── posts.py # Post management endpoints
|
84 |
-
│ └── schedules.py # Scheduling endpoints
|
85 |
-
├── services/ # Business logic
|
86 |
-
│ ├── auth_service.py # Authentication service
|
87 |
-
│ ├── linkedin_service.py# LinkedIn integration service
|
88 |
-
│ ├── content_service.py # Content generation service
|
89 |
-
│ └── schedule_service.py# Scheduling service
|
90 |
-
├── utils/ # Utility functions
|
91 |
-
│ └── database.py # Database connection
|
92 |
-
└── scheduler/ # Task scheduling
|
93 |
-
└── task_scheduler.py # Scheduling implementation
|
94 |
-
```
|
95 |
-
|
96 |
-
### Key Features
|
97 |
-
|
98 |
-
#### Authentication System
|
99 |
-
- JWT-based authentication with secure token management
|
100 |
-
- User registration with email confirmation
|
101 |
-
- User login/logout functionality
|
102 |
-
- Password hashing with bcrypt
|
103 |
-
- Supabase Auth integration
|
104 |
-
|
105 |
-
#### Source Management
|
106 |
-
- CRUD operations for RSS sources
|
107 |
-
- Integration with Supabase database
|
108 |
-
- Validation and error handling
|
109 |
-
|
110 |
-
#### Social Account Management
|
111 |
-
- LinkedIn OAuth2 integration
|
112 |
-
- Account linking and token storage
|
113 |
-
- Profile information retrieval
|
114 |
-
|
115 |
-
#### Post Management
|
116 |
-
- AI-powered content generation using Hugging Face API
|
117 |
-
- Post creation and storage
|
118 |
-
- LinkedIn publishing integration
|
119 |
-
- Image handling for posts
|
120 |
-
|
121 |
-
#### Scheduling System
|
122 |
-
- APScheduler for task management
|
123 |
-
- Recurring schedule creation
|
124 |
-
- Automatic content generation and publishing
|
125 |
-
- Conflict resolution for overlapping schedules
|
126 |
-
|
127 |
-
## Frontend Implementation
|
128 |
-
|
129 |
-
### Project Structure
|
130 |
-
|
131 |
-
```
|
132 |
-
frontend/
|
133 |
-
├── src/
|
134 |
-
│ ├── components/ # Reusable components
|
135 |
-
│ │ ├── Header/ # Application header
|
136 |
-
│ │ └── Sidebar/ # Navigation sidebar
|
137 |
-
│ ├── pages/ # Page components
|
138 |
-
│ │ ├── Login.js # Login page
|
139 |
-
│ │ ├── Register.js # Registration page
|
140 |
-
│ │ ├── Dashboard.js # Dashboard page
|
141 |
-
│ │ ├── Sources.js # Source management page
|
142 |
-
│ │ ├── Posts.js # Post management page
|
143 |
-
│ │ └── Schedule.js # Scheduling page
|
144 |
-
│ ├── services/ # API service layer
|
145 |
-
│ │ ├── api.js # Axios instance and interceptors
|
146 |
-
│ │ ├── authService.js # Authentication API calls
|
147 |
-
│ │ ├── sourceService.js# Source management API calls
|
148 |
-
│ │ ├── accountService.js# Account management API calls
|
149 |
-
│ │ ├── postService.js # Post management API calls
|
150 |
-
│ │ └── scheduleService.js# Scheduling API calls
|
151 |
-
│ ├── store/ # Redux store
|
152 |
-
│ │ ├── index.js # Store configuration
|
153 |
-
│ │ └── reducers/ # Redux reducers and actions
|
154 |
-
│ ├── App.js # Main application component
|
155 |
-
│ ├── App.css # Global application styles
|
156 |
-
│ ├── index.js # Application entry point
|
157 |
-
│ └── index.css # Global CSS styles
|
158 |
-
├── public/ # Static assets
|
159 |
-
└── package.json # Project dependencies and scripts
|
160 |
-
```
|
161 |
-
|
162 |
-
### Key Features
|
163 |
-
|
164 |
-
#### Authentication System
|
165 |
-
- Login and registration forms
|
166 |
-
- JWT token management in localStorage
|
167 |
-
- Protected routes
|
168 |
-
- User session management
|
169 |
-
|
170 |
-
#### Dashboard
|
171 |
-
- Overview statistics
|
172 |
-
- Recent activity display
|
173 |
-
- Quick action buttons
|
174 |
-
|
175 |
-
#### Source Management
|
176 |
-
- Add/delete RSS sources
|
177 |
-
- List view of all sources
|
178 |
-
- Form validation
|
179 |
-
|
180 |
-
#### Post Management
|
181 |
-
- AI content generation interface
|
182 |
-
- Post creation form
|
183 |
-
- Draft and published post management
|
184 |
-
- Publish and delete functionality
|
185 |
-
|
186 |
-
#### Scheduling
|
187 |
-
- Schedule creation form with time selection
|
188 |
-
- Day selection interface
|
189 |
-
- List view of all schedules
|
190 |
-
- Delete functionality
|
191 |
-
|
192 |
-
## API Documentation
|
193 |
-
|
194 |
-
### Authentication Endpoints
|
195 |
-
|
196 |
-
#### POST /api/auth/register
|
197 |
-
Register a new user
|
198 |
-
|
199 |
-
**Request Body:**
|
200 |
-
```json
|
201 |
-
{
|
202 |
-
"email": "string",
|
203 |
-
"password": "string",
|
204 |
-
"confirm_password": "string"
|
205 |
-
}
|
206 |
-
```
|
207 |
-
|
208 |
-
**Response:**
|
209 |
-
```json
|
210 |
-
{
|
211 |
-
"success": true,
|
212 |
-
"message": "User registered successfully",
|
213 |
-
"user": {
|
214 |
-
"id": "string",
|
215 |
-
"email": "string",
|
216 |
-
"created_at": "datetime"
|
217 |
-
}
|
218 |
-
}
|
219 |
-
```
|
220 |
-
|
221 |
-
#### POST /api/auth/login
|
222 |
-
Login user
|
223 |
-
|
224 |
-
**Request Body:**
|
225 |
-
```json
|
226 |
-
{
|
227 |
-
"email": "string",
|
228 |
-
"password": "string"
|
229 |
-
}
|
230 |
-
```
|
231 |
-
|
232 |
-
**Response:**
|
233 |
-
```json
|
234 |
-
{
|
235 |
-
"success": true,
|
236 |
-
"token": "string",
|
237 |
-
"user": {
|
238 |
-
"id": "string",
|
239 |
-
"email": "string"
|
240 |
-
}
|
241 |
-
}
|
242 |
-
```
|
243 |
-
|
244 |
-
#### POST /api/auth/logout
|
245 |
-
Logout user
|
246 |
-
|
247 |
-
**Response:**
|
248 |
-
```json
|
249 |
-
{
|
250 |
-
"success": true,
|
251 |
-
"message": "Logged out successfully"
|
252 |
-
}
|
253 |
-
```
|
254 |
-
|
255 |
-
#### GET /api/auth/user
|
256 |
-
Get current user
|
257 |
-
|
258 |
-
**Response:**
|
259 |
-
```json
|
260 |
-
{
|
261 |
-
"success": true,
|
262 |
-
"user": {
|
263 |
-
"id": "string",
|
264 |
-
"email": "string"
|
265 |
-
}
|
266 |
-
}
|
267 |
-
```
|
268 |
-
|
269 |
-
### Source Endpoints
|
270 |
-
|
271 |
-
#### GET /api/sources
|
272 |
-
Get all sources for current user
|
273 |
-
|
274 |
-
**Response:**
|
275 |
-
```json
|
276 |
-
{
|
277 |
-
"success": true,
|
278 |
-
"sources": [
|
279 |
-
{
|
280 |
-
"id": "string",
|
281 |
-
"user_id": "string",
|
282 |
-
"source": "string",
|
283 |
-
"category": "string",
|
284 |
-
"last_update": "datetime",
|
285 |
-
"created_at": "datetime"
|
286 |
-
}
|
287 |
-
]
|
288 |
-
}
|
289 |
-
```
|
290 |
-
|
291 |
-
#### POST /api/sources
|
292 |
-
Add a new source
|
293 |
-
|
294 |
-
**Request Body:**
|
295 |
-
```json
|
296 |
-
{
|
297 |
-
"source": "string"
|
298 |
-
}
|
299 |
-
```
|
300 |
-
|
301 |
-
**Response:**
|
302 |
-
```json
|
303 |
-
{
|
304 |
-
"success": true,
|
305 |
-
"source": {
|
306 |
-
"id": "string",
|
307 |
-
"user_id": "string",
|
308 |
-
"source": "string",
|
309 |
-
"category": "string",
|
310 |
-
"last_update": "datetime",
|
311 |
-
"created_at": "datetime"
|
312 |
-
}
|
313 |
-
}
|
314 |
-
```
|
315 |
-
|
316 |
-
#### DELETE /api/sources/{id}
|
317 |
-
Delete a source
|
318 |
-
|
319 |
-
**Response:**
|
320 |
-
```json
|
321 |
-
{
|
322 |
-
"success": true,
|
323 |
-
"message": "Source deleted successfully"
|
324 |
-
}
|
325 |
-
```
|
326 |
-
|
327 |
-
### Account Endpoints
|
328 |
-
|
329 |
-
#### GET /api/accounts
|
330 |
-
Get all social accounts for current user
|
331 |
-
|
332 |
-
**Response:**
|
333 |
-
```json
|
334 |
-
{
|
335 |
-
"success": true,
|
336 |
-
"accounts": [
|
337 |
-
{
|
338 |
-
"id": "string",
|
339 |
-
"user_id": "string",
|
340 |
-
"social_network": "string",
|
341 |
-
"account_name": "string",
|
342 |
-
"created_at": "datetime"
|
343 |
-
}
|
344 |
-
]
|
345 |
-
}
|
346 |
-
```
|
347 |
-
|
348 |
-
#### POST /api/accounts
|
349 |
-
Add a new social account
|
350 |
-
|
351 |
-
**Request Body:**
|
352 |
-
```json
|
353 |
-
{
|
354 |
-
"account_name": "string",
|
355 |
-
"social_network": "string"
|
356 |
-
}
|
357 |
-
```
|
358 |
-
|
359 |
-
**Response:**
|
360 |
-
```json
|
361 |
-
{
|
362 |
-
"success": true,
|
363 |
-
"account": {
|
364 |
-
"id": "string",
|
365 |
-
"user_id": "string",
|
366 |
-
"social_network": "string",
|
367 |
-
"account_name": "string",
|
368 |
-
"created_at": "datetime"
|
369 |
-
}
|
370 |
-
}
|
371 |
-
```
|
372 |
-
|
373 |
-
#### DELETE /api/accounts/{id}
|
374 |
-
Delete a social account
|
375 |
-
|
376 |
-
**Response:**
|
377 |
-
```json
|
378 |
-
{
|
379 |
-
"success": true,
|
380 |
-
"message": "Account deleted successfully"
|
381 |
-
}
|
382 |
-
```
|
383 |
-
|
384 |
-
### Post Endpoints
|
385 |
-
|
386 |
-
#### GET /api/posts
|
387 |
-
Get all posts for current user
|
388 |
-
|
389 |
-
**Query Parameters:**
|
390 |
-
- `published` (boolean): Filter by published status
|
391 |
-
|
392 |
-
**Response:**
|
393 |
-
```json
|
394 |
-
{
|
395 |
-
"success": true,
|
396 |
-
"posts": [
|
397 |
-
{
|
398 |
-
"id": "string",
|
399 |
-
"social_account_id": "string",
|
400 |
-
"text_content": "string",
|
401 |
-
"is_published": "boolean",
|
402 |
-
"sched": "string",
|
403 |
-
"image_content_url": "string",
|
404 |
-
"created_at": "datetime",
|
405 |
-
"scheduled_at": "datetime"
|
406 |
-
}
|
407 |
-
]
|
408 |
-
}
|
409 |
-
```
|
410 |
-
|
411 |
-
#### POST /api/posts/generate
|
412 |
-
Generate AI content
|
413 |
-
|
414 |
-
**Response:**
|
415 |
-
```json
|
416 |
-
{
|
417 |
-
"success": true,
|
418 |
-
"content": "string"
|
419 |
-
}
|
420 |
-
```
|
421 |
-
|
422 |
-
#### POST /api/posts
|
423 |
-
Create a new post
|
424 |
-
|
425 |
-
**Request Body:**
|
426 |
-
```json
|
427 |
-
{
|
428 |
-
"social_account_id": "string",
|
429 |
-
"text_content": "string",
|
430 |
-
"image_content_url": "string",
|
431 |
-
"scheduled_at": "datetime"
|
432 |
-
}
|
433 |
-
```
|
434 |
-
|
435 |
-
**Response:**
|
436 |
-
```json
|
437 |
-
{
|
438 |
-
"success": true,
|
439 |
-
"post": {
|
440 |
-
"id": "string",
|
441 |
-
"social_account_id": "string",
|
442 |
-
"text_content": "string",
|
443 |
-
"is_published": "boolean",
|
444 |
-
"sched": "string",
|
445 |
-
"image_content_url": "string",
|
446 |
-
"created_at": "datetime",
|
447 |
-
"scheduled_at": "datetime"
|
448 |
-
}
|
449 |
-
}
|
450 |
-
```
|
451 |
-
|
452 |
-
#### POST /api/posts/{id}/publish
|
453 |
-
Publish a post
|
454 |
-
|
455 |
-
**Response:**
|
456 |
-
```json
|
457 |
-
{
|
458 |
-
"success": true,
|
459 |
-
"message": "Post published successfully"
|
460 |
-
}
|
461 |
-
```
|
462 |
-
|
463 |
-
#### DELETE /api/posts/{id}
|
464 |
-
Delete a post
|
465 |
-
|
466 |
-
**Response:**
|
467 |
-
```json
|
468 |
-
{
|
469 |
-
"success": true,
|
470 |
-
"message": "Post deleted successfully"
|
471 |
-
}
|
472 |
-
```
|
473 |
-
|
474 |
-
### Schedule Endpoints
|
475 |
-
|
476 |
-
#### GET /api/schedules
|
477 |
-
Get all schedules for current user
|
478 |
-
|
479 |
-
**Response:**
|
480 |
-
```json
|
481 |
-
{
|
482 |
-
"success": true,
|
483 |
-
"schedules": [
|
484 |
-
{
|
485 |
-
"id": "string",
|
486 |
-
"social_account_id": "string",
|
487 |
-
"schedule_time": "string",
|
488 |
-
"adjusted_time": "string",
|
489 |
-
"created_at": "datetime"
|
490 |
-
}
|
491 |
-
]
|
492 |
-
}
|
493 |
-
```
|
494 |
-
|
495 |
-
#### POST /api/schedules
|
496 |
-
Create a new schedule
|
497 |
-
|
498 |
-
**Request Body:**
|
499 |
-
```json
|
500 |
-
{
|
501 |
-
"social_network": "string",
|
502 |
-
"schedule_time": "string",
|
503 |
-
"days": ["string"]
|
504 |
-
}
|
505 |
-
```
|
506 |
-
|
507 |
-
**Response:**
|
508 |
-
```json
|
509 |
-
{
|
510 |
-
"success": true,
|
511 |
-
"schedules": [
|
512 |
-
{
|
513 |
-
"id": "string",
|
514 |
-
"social_account_id": "string",
|
515 |
-
"schedule_time": "string",
|
516 |
-
"adjusted_time": "string",
|
517 |
-
"created_at": "datetime"
|
518 |
-
}
|
519 |
-
]
|
520 |
-
}
|
521 |
-
```
|
522 |
-
|
523 |
-
#### DELETE /api/schedules/{id}
|
524 |
-
Delete a schedule
|
525 |
-
|
526 |
-
**Response:**
|
527 |
-
```json
|
528 |
-
{
|
529 |
-
"success": true,
|
530 |
-
"message": "Schedule deleted successfully"
|
531 |
-
}
|
532 |
-
```
|
533 |
-
|
534 |
-
## Deployment Guide
|
535 |
-
|
536 |
-
### Backend Deployment
|
537 |
-
|
538 |
-
1. **Environment Setup**
|
539 |
-
```bash
|
540 |
-
# Copy environment example
|
541 |
-
cp .env.example .env
|
542 |
-
|
543 |
-
# Edit .env with your values
|
544 |
-
```
|
545 |
-
|
546 |
-
2. **Install Dependencies**
|
547 |
-
```bash
|
548 |
-
pip install -r requirements.txt
|
549 |
-
```
|
550 |
-
|
551 |
-
3. **Run Application**
|
552 |
-
```bash
|
553 |
-
python app.py
|
554 |
-
```
|
555 |
-
|
556 |
-
4. **Docker Deployment**
|
557 |
-
```bash
|
558 |
-
docker build -t lin-backend .
|
559 |
-
docker run -p 5000:5000 lin-backend
|
560 |
-
```
|
561 |
-
|
562 |
-
### Frontend Deployment
|
563 |
-
|
564 |
-
1. **Install Dependencies**
|
565 |
-
```bash
|
566 |
-
npm install
|
567 |
-
```
|
568 |
-
|
569 |
-
2. **Build for Production**
|
570 |
-
```bash
|
571 |
-
npm run build
|
572 |
-
```
|
573 |
-
|
574 |
-
3. **Serve Build**
|
575 |
-
```bash
|
576 |
-
npm install -g serve
|
577 |
-
serve -s build
|
578 |
-
```
|
579 |
-
|
580 |
-
### Environment Variables
|
581 |
-
|
582 |
-
#### Backend (.env)
|
583 |
-
```
|
584 |
-
SUPABASE_URL=your_supabase_project_url
|
585 |
-
SUPABASE_KEY=your_supabase_api_key
|
586 |
-
CLIENT_ID=your_linkedin_client_id
|
587 |
-
CLIENT_SECRET=your_linkedin_client_secret
|
588 |
-
REDIRECT_URL=your_redirect_url
|
589 |
-
HUGGING_KEY=your_hugging_face_api_key
|
590 |
-
JWT_SECRET_KEY=your_jwt_secret_key
|
591 |
-
SECRET_KEY=your_secret_key
|
592 |
-
DEBUG=True
|
593 |
-
SCHEDULER_ENABLED=True
|
594 |
-
PORT=5000
|
595 |
-
```
|
596 |
-
|
597 |
-
#### Frontend (.env)
|
598 |
-
```
|
599 |
-
REACT_APP_API_URL=http://localhost:5000/api
|
600 |
-
```
|
601 |
-
|
602 |
-
## Testing Strategy
|
603 |
-
|
604 |
-
### Backend Testing
|
605 |
-
|
606 |
-
1. **Unit Tests**
|
607 |
-
- Model validation tests
|
608 |
-
- Service layer tests
|
609 |
-
- Utility function tests
|
610 |
-
|
611 |
-
2. **Integration Tests**
|
612 |
-
- API endpoint tests
|
613 |
-
- Database integration tests
|
614 |
-
- External API integration tests
|
615 |
-
|
616 |
-
3. **Test Commands**
|
617 |
-
```bash
|
618 |
-
# Run all tests
|
619 |
-
pytest
|
620 |
-
|
621 |
-
# Run tests with coverage
|
622 |
-
pytest --cov=.
|
623 |
-
```
|
624 |
-
|
625 |
-
### Frontend Testing
|
626 |
-
|
627 |
-
1. **Component Tests**
|
628 |
-
- Rendering tests
|
629 |
-
- User interaction tests
|
630 |
-
- State management tests
|
631 |
-
|
632 |
-
2. **Integration Tests**
|
633 |
-
- Form submission tests
|
634 |
-
- API integration tests
|
635 |
-
- Routing tests
|
636 |
-
|
637 |
-
3. **Test Commands**
|
638 |
-
```bash
|
639 |
-
# Run all tests
|
640 |
-
npm test
|
641 |
-
|
642 |
-
# Run tests in watch mode
|
643 |
-
npm test -- --watch
|
644 |
-
```
|
645 |
-
|
646 |
-
## Future Enhancements
|
647 |
-
|
648 |
-
### Backend Enhancements
|
649 |
-
1. **Advanced Analytics**
|
650 |
-
- Post performance tracking
|
651 |
-
- User engagement metrics
|
652 |
-
- Content effectiveness analysis
|
653 |
-
|
654 |
-
2. **Multi-Platform Support**
|
655 |
-
- Twitter integration
|
656 |
-
- Facebook integration
|
657 |
-
- Instagram integration
|
658 |
-
|
659 |
-
3. **Enhanced Scheduling**
|
660 |
-
- Advanced scheduling algorithms
|
661 |
-
- Timezone support
|
662 |
-
- Recurrence patterns
|
663 |
-
|
664 |
-
4. **Performance Improvements**
|
665 |
-
- Caching strategies
|
666 |
-
- Database optimization
|
667 |
-
- Asynchronous processing
|
668 |
-
|
669 |
-
### Frontend Enhancements
|
670 |
-
1. **Advanced UI Components**
|
671 |
-
- Data visualization dashboards
|
672 |
-
- Real-time updates
|
673 |
-
- Drag-and-drop scheduling
|
674 |
-
|
675 |
-
2. **Enhanced User Experience**
|
676 |
-
- Dark mode support
|
677 |
-
- Keyboard shortcuts
|
678 |
-
- Accessibility improvements
|
679 |
-
|
680 |
-
3. **Mobile Enhancements**
|
681 |
-
- Progressive Web App (PWA) support
|
682 |
-
- Native mobile features
|
683 |
-
- Offline capabilities
|
684 |
-
|
685 |
-
4. **Advanced Features**
|
686 |
-
- Content calendar view
|
687 |
-
- Team collaboration features
|
688 |
-
- Content approval workflows
|
689 |
-
|
690 |
-
## Conclusion
|
691 |
-
|
692 |
-
The Lin React Clone project successfully reimplements the original Taipy-based application with a modern, scalable architecture. The separation of concerns between the frontend and backend allows for independent development and deployment, while the RESTful API design ensures clear communication between components. The implementation includes all core features of the original application while providing a foundation for future enhancements and improvements.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LINKEDIN_AUTH_GUIDE.md
DELETED
@@ -1,258 +0,0 @@
|
|
1 |
-
# LinkedIn Authentication Implementation Guide
|
2 |
-
|
3 |
-
This guide provides a comprehensive overview of the LinkedIn authentication implementation in the React Clone application.
|
4 |
-
|
5 |
-
## Overview
|
6 |
-
|
7 |
-
The LinkedIn authentication system allows users to connect multiple LinkedIn accounts to the application for posting content. The implementation follows OAuth 2.0 standards and includes proper error handling, state management, and user experience considerations.
|
8 |
-
|
9 |
-
## Architecture
|
10 |
-
|
11 |
-
### Frontend Components
|
12 |
-
|
13 |
-
1. **LinkedInAuthService** (`frontend/src/services/linkedinAuthService.js`)
|
14 |
-
- Handles all API calls related to LinkedIn authentication
|
15 |
-
- Manages OAuth flow initiation and callback processing
|
16 |
-
- Provides methods for account management
|
17 |
-
|
18 |
-
2. **LinkedInAccountsSlice** (`frontend/src/store/reducers/linkedinAccountsSlice.js`)
|
19 |
-
- Redux slice for managing LinkedIn accounts state
|
20 |
-
- Handles async operations for fetching, adding, and managing accounts
|
21 |
-
- Manages loading states and error handling
|
22 |
-
|
23 |
-
3. **LinkedInAccountsManager** (`frontend/src/components/LinkedInAccount/LinkedInAccountsManager.js`)
|
24 |
-
- Main component for managing LinkedIn accounts
|
25 |
-
- Displays connected accounts and provides management options
|
26 |
-
- Handles the "Add Account" flow
|
27 |
-
|
28 |
-
4. **LinkedInAccountCard** (`frontend/src/components/LinkedInAccount/LinkedInAccountCard.js`)
|
29 |
-
- Individual account display component
|
30 |
-
- Shows account information and actions (set primary, delete)
|
31 |
-
- Handles account-specific operations
|
32 |
-
|
33 |
-
5. **LinkedInCallbackHandler** (`frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.js`)
|
34 |
-
- Handles the OAuth callback from LinkedIn
|
35 |
-
- Processes authorization code and exchanges it for access token
|
36 |
-
- Manages authentication states and error handling
|
37 |
-
|
38 |
-
6. **Accounts Page** (`frontend/src/pages/Accounts.js`)
|
39 |
-
- Dedicated page for managing all social media accounts
|
40 |
-
- Provides a clean interface for LinkedIn account management
|
41 |
-
- Separates account management from RSS source management
|
42 |
-
|
43 |
-
### Backend API
|
44 |
-
|
45 |
-
1. **Accounts API** (`backend/api/accounts.py`)
|
46 |
-
- `/accounts` - GET: Fetch all accounts, POST: Initiate OAuth flow
|
47 |
-
- `/accounts/callback` - POST: Handle OAuth callback
|
48 |
-
- `/accounts/{id}` - DELETE: Remove account
|
49 |
-
- `/accounts/{id}/primary` - PUT: Set account as primary
|
50 |
-
|
51 |
-
2. **LinkedInService** (`backend/services/linkedin_service.py`)
|
52 |
-
- Handles LinkedIn API interactions
|
53 |
-
- Manages OAuth token exchange
|
54 |
-
- Provides methods for user info retrieval and posting
|
55 |
-
|
56 |
-
## Implementation Details
|
57 |
-
|
58 |
-
### OAuth Flow
|
59 |
-
|
60 |
-
1. **Initiation**
|
61 |
-
- User clicks "Add LinkedIn Account" button on the Accounts page
|
62 |
-
- Frontend calls `/accounts` endpoint with `social_network: 'LinkedIn'`
|
63 |
-
- Backend generates authorization URL and state parameter
|
64 |
-
- User is redirected to LinkedIn for authentication
|
65 |
-
|
66 |
-
2. **Callback Handling**
|
67 |
-
- LinkedIn redirects back to `/linkedin/callback` with authorization code
|
68 |
-
- Frontend processes the callback and exchanges code for access token
|
69 |
-
- Backend validates the code and retrieves user information
|
70 |
-
- Account information is stored in the database
|
71 |
-
|
72 |
-
3. **Account Management**
|
73 |
-
- Users can view all connected LinkedIn accounts on the Accounts page
|
74 |
-
- Primary account can be set for posting operations
|
75 |
-
- Accounts can be disconnected (deleted)
|
76 |
-
|
77 |
-
### State Management
|
78 |
-
|
79 |
-
The Redux store manages the following states for LinkedIn accounts:
|
80 |
-
|
81 |
-
```javascript
|
82 |
-
{
|
83 |
-
linkedinAccounts: {
|
84 |
-
items: [], // Array of LinkedIn accounts
|
85 |
-
loading: false, // Loading state
|
86 |
-
error: null, // Error message
|
87 |
-
oauthLoading: false, // OAuth process loading
|
88 |
-
oauthError: null, // OAuth error message
|
89 |
-
deletingAccount: null, // ID of account being deleted
|
90 |
-
settingPrimary: null // ID of account being set as primary
|
91 |
-
}
|
92 |
-
}
|
93 |
-
```
|
94 |
-
|
95 |
-
### Database Schema
|
96 |
-
|
97 |
-
LinkedIn accounts are stored in the `Social_network` table with the following fields:
|
98 |
-
|
99 |
-
- `id`: Unique identifier
|
100 |
-
- `social_network`: 'LinkedIn'
|
101 |
-
- `account_name`: Display name for the account
|
102 |
-
- `id_utilisateur`: User ID (foreign key)
|
103 |
-
- `token`: LinkedIn access token
|
104 |
-
- `sub`: LinkedIn user ID
|
105 |
-
- `given_name`: User's first name
|
106 |
-
- `family_name`: User's last name
|
107 |
-
- `picture`: Profile picture URL
|
108 |
-
- `is_primary`: Boolean flag for primary account
|
109 |
-
|
110 |
-
## Usage Instructions
|
111 |
-
|
112 |
-
### Adding a LinkedIn Account
|
113 |
-
|
114 |
-
1. Navigate to the **Accounts** page (`/accounts`)
|
115 |
-
2. Click **"Add LinkedIn Account"**
|
116 |
-
3. Follow the LinkedIn authentication flow
|
117 |
-
4. After successful authentication, the account will appear in the list
|
118 |
-
|
119 |
-
### Managing LinkedIn Accounts
|
120 |
-
|
121 |
-
1. **View Accounts**: All connected accounts are displayed on the Accounts page
|
122 |
-
2. **Set Primary**: Click "Set Primary" on the desired account
|
123 |
-
3. **Disconnect**: Click "Disconnect" to remove an account (confirmation required)
|
124 |
-
|
125 |
-
### Page Structure
|
126 |
-
|
127 |
-
- **Sources Page** (`/sources`): Dedicated to RSS source management only
|
128 |
-
- **Accounts Page** (`/accounts`): Dedicated to social media account management
|
129 |
-
|
130 |
-
### Error Handling
|
131 |
-
|
132 |
-
The implementation includes comprehensive error handling:
|
133 |
-
|
134 |
-
- **OAuth Errors**: Invalid state, expired authorization codes
|
135 |
-
- **Network Errors**: API timeouts, connection issues
|
136 |
-
- **Authentication Errors**: Invalid tokens, permission denied
|
137 |
-
- **Database Errors**: Failed storage operations
|
138 |
-
|
139 |
-
### Security Considerations
|
140 |
-
|
141 |
-
1. **State Parameter**: Randomly generated state parameter for CSRF protection
|
142 |
-
2. **Token Storage**: Access tokens are stored securely in the database
|
143 |
-
3. **User Validation**: All operations are validated against the authenticated user
|
144 |
-
4. **HTTPS**: All API calls use HTTPS for secure communication
|
145 |
-
|
146 |
-
## Configuration
|
147 |
-
|
148 |
-
### Environment Variables
|
149 |
-
|
150 |
-
Ensure the following environment variables are set:
|
151 |
-
|
152 |
-
```bash
|
153 |
-
# LinkedIn OAuth Configuration
|
154 |
-
CLIENT_ID=your_linkedin_client_id
|
155 |
-
CLIENT_SECRET=your_linkedin_client_secret
|
156 |
-
REDIRECT_URL=your_redirect_url
|
157 |
-
|
158 |
-
# Supabase Configuration
|
159 |
-
SUPABASE_URL=your_supabase_url
|
160 |
-
SUPABASE_KEY=your_supabase_key
|
161 |
-
```
|
162 |
-
|
163 |
-
### Backend Configuration
|
164 |
-
|
165 |
-
The backend uses the following LinkedIn API endpoints:
|
166 |
-
|
167 |
-
- Authorization: `https://www.linkedin.com/oauth/v2/authorization`
|
168 |
-
- Token Exchange: `https://www.linkedin.com/oauth/v2/accessToken`
|
169 |
-
- User Info: `https://api.linkedin.com/v2/userinfo`
|
170 |
-
|
171 |
-
## Testing
|
172 |
-
|
173 |
-
### Manual Testing Steps
|
174 |
-
|
175 |
-
1. **Account Addition**
|
176 |
-
- Navigate to Accounts page
|
177 |
-
- Click "Add LinkedIn Account"
|
178 |
-
- Complete OAuth flow
|
179 |
-
- Verify account appears in the list
|
180 |
-
|
181 |
-
2. **Account Management**
|
182 |
-
- Test setting primary account
|
183 |
-
- Test disconnecting accounts
|
184 |
-
- Verify error states and loading indicators
|
185 |
-
|
186 |
-
3. **Page Navigation**
|
187 |
-
- Verify Sources page only shows RSS sources
|
188 |
-
- Verify Accounts page only shows social media accounts
|
189 |
-
- Test navigation between pages
|
190 |
-
|
191 |
-
### Automated Testing
|
192 |
-
|
193 |
-
The implementation includes Redux action and reducer tests that can be extended with:
|
194 |
-
|
195 |
-
- OAuth flow simulation
|
196 |
-
- API mocking
|
197 |
-
- State validation
|
198 |
-
- Error condition testing
|
199 |
-
|
200 |
-
## Troubleshooting
|
201 |
-
|
202 |
-
### Common Issues
|
203 |
-
|
204 |
-
1. **OAuth State Mismatch**
|
205 |
-
- Ensure state parameter is properly generated and stored
|
206 |
-
- Check for proper state validation in callback handling
|
207 |
-
|
208 |
-
2. **Token Exchange Failures**
|
209 |
-
- Verify client ID and client secret are correct
|
210 |
-
- Ensure redirect URL matches configuration
|
211 |
-
- Check for expired authorization codes
|
212 |
-
|
213 |
-
3. **Account Not Displaying**
|
214 |
-
- Verify database insertion was successful
|
215 |
-
- Check user ID mapping
|
216 |
-
- Ensure API response is properly formatted
|
217 |
-
|
218 |
-
4. **Page Navigation Issues**
|
219 |
-
- Verify routes are properly configured in App.js
|
220 |
-
- Check that components are imported correctly
|
221 |
-
- Ensure Redux state is properly connected
|
222 |
-
|
223 |
-
### Debug Mode
|
224 |
-
|
225 |
-
Enable debug logging by setting:
|
226 |
-
|
227 |
-
```javascript
|
228 |
-
// In development mode
|
229 |
-
localStorage.setItem('debug', 'linkedin:*');
|
230 |
-
|
231 |
-
// Backend logging
|
232 |
-
export DEBUG=True
|
233 |
-
```
|
234 |
-
|
235 |
-
## Future Enhancements
|
236 |
-
|
237 |
-
1. **Token Refresh**: Implement automatic token refresh
|
238 |
-
2. **Account Permissions**: Request specific LinkedIn permissions
|
239 |
-
3. **Batch Operations**: Support for managing multiple accounts simultaneously
|
240 |
-
4. **Analytics**: Track account usage and posting statistics
|
241 |
-
5. **Webhooks**: Implement LinkedIn webhook support for real-time updates
|
242 |
-
6. **Additional Social Networks**: Extend to Twitter, Facebook, etc.
|
243 |
-
|
244 |
-
## Support
|
245 |
-
|
246 |
-
For issues or questions regarding the LinkedIn authentication implementation:
|
247 |
-
|
248 |
-
1. Check the troubleshooting section above
|
249 |
-
2. Review browser console and network tab for errors
|
250 |
-
3. Check backend logs for API-related issues
|
251 |
-
4. Verify environment configuration
|
252 |
-
5. Ensure proper page navigation and routing
|
253 |
-
|
254 |
-
## References
|
255 |
-
|
256 |
-
- [LinkedIn OAuth 2.0 Documentation](https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin)
|
257 |
-
- [React Redux Toolkit Documentation](https://redux-toolkit.js.org/)
|
258 |
-
- [OAuth 2.0 Framework](https://datatracker.ietf.org/doc/html/rfc6749)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MIGRATION_TO_APSCHEDULER.md
DELETED
@@ -1,84 +0,0 @@
|
|
1 |
-
# Migrating from Celery to APScheduler
|
2 |
-
|
3 |
-
This guide explains how to migrate from Celery to APScheduler in the Lin application.
|
4 |
-
|
5 |
-
## Why Migrate to APScheduler?
|
6 |
-
|
7 |
-
1. **Simplified Architecture**: APScheduler runs within the Flask application process, eliminating the need for separate worker processes
|
8 |
-
2. **No External Dependencies**: Unlike Celery which requires Redis or RabbitMQ, APScheduler uses in-memory storage by default
|
9 |
-
3. **Easier Deployment**: Simplifies deployment since there are fewer components to manage
|
10 |
-
4. **Reduced Resource Usage**: Uses less memory and CPU compared to running separate Celery processes
|
11 |
-
|
12 |
-
## Changes Made
|
13 |
-
|
14 |
-
### 1. Removed Dependencies
|
15 |
-
- Removed `celery` and `redis` from `requirements.txt`
|
16 |
-
- Kept `apscheduler` as the scheduling library
|
17 |
-
|
18 |
-
### 2. New Scheduler Service
|
19 |
-
- Created `backend/scheduler/apscheduler_service.py` to handle all scheduling tasks
|
20 |
-
- Implemented content generation and post publishing as APScheduler jobs
|
21 |
-
|
22 |
-
### 3. Updated Flask Application
|
23 |
-
- Modified `backend/app.py` to initialize APScheduler instead of Celery
|
24 |
-
- Added scheduler initialization when `SCHEDULER_ENABLED` is True
|
25 |
-
|
26 |
-
### 4. Updated API Endpoints
|
27 |
-
- Modified `backend/api/schedules.py` to trigger APScheduler updates instead of Celery tasks
|
28 |
-
- Removed all references to Celery task IDs in responses
|
29 |
-
|
30 |
-
### 5. Simplified Startup Script
|
31 |
-
- Updated `start_app.py` to remove Celery component initialization
|
32 |
-
- The application now starts with just Flask and APScheduler
|
33 |
-
|
34 |
-
### 6. Removed Files
|
35 |
-
- Removed `backend/celery_app.py`
|
36 |
-
- Removed `backend/celery_config.py`
|
37 |
-
- Removed `backend/celery_tasks/` directory
|
38 |
-
- Removed `backend/start_celery.py`
|
39 |
-
|
40 |
-
## Migration Steps
|
41 |
-
|
42 |
-
### 1. Update Dependencies
|
43 |
-
```bash
|
44 |
-
# Update requirements
|
45 |
-
pip install -r backend/requirements.txt
|
46 |
-
```
|
47 |
-
|
48 |
-
### 2. Update Environment Variables
|
49 |
-
No changes needed for basic setup. The scheduler is enabled by default.
|
50 |
-
|
51 |
-
### 3. Remove Old Components
|
52 |
-
The old Celery components have been removed from the codebase.
|
53 |
-
|
54 |
-
### 4. Verify Functionality
|
55 |
-
1. Start the application:
|
56 |
-
```bash
|
57 |
-
python start_app.py
|
58 |
-
```
|
59 |
-
|
60 |
-
2. Create a test schedule via the API
|
61 |
-
|
62 |
-
3. Check the console logs to verify that schedules are being loaded and tasks are being created
|
63 |
-
|
64 |
-
## Benefits of the Migration
|
65 |
-
|
66 |
-
1. **Simpler Setup**: No need to install and configure Redis
|
67 |
-
2. **Easier Debugging**: All logs are in one place
|
68 |
-
3. **Reduced Complexity**: Fewer moving parts to manage
|
69 |
-
4. **Better Resource Usage**: Lower memory and CPU footprint
|
70 |
-
5. **Simplified Deployment**: Single process deployment
|
71 |
-
|
72 |
-
## Potential Considerations
|
73 |
-
|
74 |
-
1. **Scalability**: For high-volume applications, Celery with multiple workers might be more appropriate
|
75 |
-
2. **Persistence**: APScheduler uses in-memory storage by default, which means schedules are lost on application restart (this is mitigated by reloading from the database every 5 minutes)
|
76 |
-
3. **Task Isolation**: All tasks run in the same process, so a long-running task could block others
|
77 |
-
|
78 |
-
## Support
|
79 |
-
|
80 |
-
If you encounter issues during migration:
|
81 |
-
1. Check the application logs for error messages
|
82 |
-
2. Verify that all dependencies are correctly installed
|
83 |
-
3. Ensure the Supabase connection is working
|
84 |
-
4. Test creating and deleting schedules via the API
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
api_design.md
DELETED
@@ -1,348 +0,0 @@
|
|
1 |
-
# API Design Document
|
2 |
-
|
3 |
-
## Overview
|
4 |
-
This document outlines the RESTful API endpoints for the Lin application backend. The API will be implemented using Flask and will follow REST conventions.
|
5 |
-
|
6 |
-
## Authentication
|
7 |
-
All endpoints (except authentication endpoints) require a valid JWT token in the Authorization header:
|
8 |
-
```
|
9 |
-
Authorization: Bearer <token>
|
10 |
-
```
|
11 |
-
|
12 |
-
## Error Handling
|
13 |
-
All endpoints will return appropriate HTTP status codes:
|
14 |
-
- 200: Success
|
15 |
-
- 201: Created
|
16 |
-
- 400: Bad Request
|
17 |
-
- 401: Unauthorized
|
18 |
-
- 404: Not Found
|
19 |
-
- 500: Internal Server Error
|
20 |
-
|
21 |
-
Error responses will follow this format:
|
22 |
-
```json
|
23 |
-
{
|
24 |
-
"error": "Error message",
|
25 |
-
"code": "ERROR_CODE"
|
26 |
-
}
|
27 |
-
```
|
28 |
-
|
29 |
-
## Endpoints
|
30 |
-
|
31 |
-
### Authentication
|
32 |
-
|
33 |
-
#### Register User
|
34 |
-
- **POST** `/api/auth/register`
|
35 |
-
- **Description**: Register a new user
|
36 |
-
- **Request Body**:
|
37 |
-
```json
|
38 |
-
{
|
39 |
-
"email": "string",
|
40 |
-
"password": "string",
|
41 |
-
"confirm_password": "string"
|
42 |
-
}
|
43 |
-
```
|
44 |
-
- **Response**:
|
45 |
-
```json
|
46 |
-
{
|
47 |
-
"message": "User registered successfully",
|
48 |
-
"user": {
|
49 |
-
"id": "string",
|
50 |
-
"email": "string"
|
51 |
-
}
|
52 |
-
}
|
53 |
-
```
|
54 |
-
|
55 |
-
#### Login User
|
56 |
-
- **POST** `/api/auth/login`
|
57 |
-
- **Description**: Authenticate a user
|
58 |
-
- **Request Body**:
|
59 |
-
```json
|
60 |
-
{
|
61 |
-
"email": "string",
|
62 |
-
"password": "string"
|
63 |
-
}
|
64 |
-
```
|
65 |
-
- **Response**:
|
66 |
-
```json
|
67 |
-
{
|
68 |
-
"token": "string",
|
69 |
-
"user": {
|
70 |
-
"id": "string",
|
71 |
-
"email": "string"
|
72 |
-
}
|
73 |
-
}
|
74 |
-
```
|
75 |
-
|
76 |
-
#### Logout User
|
77 |
-
- **POST** `/api/auth/logout`
|
78 |
-
- **Description**: Logout current user
|
79 |
-
- **Response**:
|
80 |
-
```json
|
81 |
-
{
|
82 |
-
"message": "Logged out successfully"
|
83 |
-
}
|
84 |
-
```
|
85 |
-
|
86 |
-
#### Get Current User
|
87 |
-
- **GET** `/api/auth/user`
|
88 |
-
- **Description**: Get current authenticated user
|
89 |
-
- **Response**:
|
90 |
-
```json
|
91 |
-
{
|
92 |
-
"user": {
|
93 |
-
"id": "string",
|
94 |
-
"email": "string"
|
95 |
-
}
|
96 |
-
}
|
97 |
-
```
|
98 |
-
|
99 |
-
### Sources
|
100 |
-
|
101 |
-
#### Get All Sources
|
102 |
-
- **GET** `/api/sources`
|
103 |
-
- **Description**: Get all sources for the current user
|
104 |
-
- **Response**:
|
105 |
-
```json
|
106 |
-
{
|
107 |
-
"sources": [
|
108 |
-
{
|
109 |
-
"id": "string",
|
110 |
-
"user_id": "string",
|
111 |
-
"source": "string",
|
112 |
-
"category": "string",
|
113 |
-
"last_update": "datetime"
|
114 |
-
}
|
115 |
-
]
|
116 |
-
}
|
117 |
-
```
|
118 |
-
|
119 |
-
#### Add Source
|
120 |
-
- **POST** `/api/sources`
|
121 |
-
- **Description**: Add a new source
|
122 |
-
- **Request Body**:
|
123 |
-
```json
|
124 |
-
{
|
125 |
-
"source": "string"
|
126 |
-
}
|
127 |
-
```
|
128 |
-
- **Response**:
|
129 |
-
```json
|
130 |
-
{
|
131 |
-
"message": "Source added successfully",
|
132 |
-
"source": {
|
133 |
-
"id": "string",
|
134 |
-
"user_id": "string",
|
135 |
-
"source": "string",
|
136 |
-
"category": "string",
|
137 |
-
"last_update": "datetime"
|
138 |
-
}
|
139 |
-
}
|
140 |
-
```
|
141 |
-
|
142 |
-
#### Delete Source
|
143 |
-
- **DELETE** `/api/sources/{id}`
|
144 |
-
- **Description**: Delete a source
|
145 |
-
- **Response**:
|
146 |
-
```json
|
147 |
-
{
|
148 |
-
"message": "Source deleted successfully"
|
149 |
-
}
|
150 |
-
```
|
151 |
-
|
152 |
-
### Social Accounts
|
153 |
-
|
154 |
-
#### Get All Accounts
|
155 |
-
- **GET** `/api/accounts`
|
156 |
-
- **Description**: Get all social media accounts for the current user
|
157 |
-
- **Response**:
|
158 |
-
```json
|
159 |
-
{
|
160 |
-
"accounts": [
|
161 |
-
{
|
162 |
-
"id": "string",
|
163 |
-
"user_id": "string",
|
164 |
-
"social_network": "string",
|
165 |
-
"account_name": "string",
|
166 |
-
"created_at": "datetime"
|
167 |
-
}
|
168 |
-
]
|
169 |
-
}
|
170 |
-
```
|
171 |
-
|
172 |
-
#### Add Account
|
173 |
-
- **POST** `/api/accounts`
|
174 |
-
- **Description**: Add a new social media account
|
175 |
-
- **Request Body**:
|
176 |
-
```json
|
177 |
-
{
|
178 |
-
"account_name": "string",
|
179 |
-
"social_network": "string"
|
180 |
-
}
|
181 |
-
```
|
182 |
-
- **Response**:
|
183 |
-
```json
|
184 |
-
{
|
185 |
-
"message": "Account added successfully",
|
186 |
-
"account": {
|
187 |
-
"id": "string",
|
188 |
-
"user_id": "string",
|
189 |
-
"social_network": "string",
|
190 |
-
"account_name": "string",
|
191 |
-
"created_at": "datetime"
|
192 |
-
}
|
193 |
-
}
|
194 |
-
```
|
195 |
-
|
196 |
-
#### Delete Account
|
197 |
-
- **DELETE** `/api/accounts/{id}`
|
198 |
-
- **Description**: Delete a social media account
|
199 |
-
- **Response**:
|
200 |
-
```json
|
201 |
-
{
|
202 |
-
"message": "Account deleted successfully"
|
203 |
-
}
|
204 |
-
```
|
205 |
-
|
206 |
-
### Posts
|
207 |
-
|
208 |
-
#### Get All Posts
|
209 |
-
- **GET** `/api/posts`
|
210 |
-
- **Description**: Get all posts for the current user
|
211 |
-
- **Query Parameters**:
|
212 |
-
- `published` (boolean): Filter by published status
|
213 |
-
- **Response**:
|
214 |
-
```json
|
215 |
-
{
|
216 |
-
"posts": [
|
217 |
-
{
|
218 |
-
"id": "string",
|
219 |
-
"user_id": "string",
|
220 |
-
"social_account_id": "string",
|
221 |
-
"text_content": "string",
|
222 |
-
"image_content_url": "string",
|
223 |
-
"is_published": "boolean",
|
224 |
-
"created_at": "datetime",
|
225 |
-
"scheduled_at": "datetime"
|
226 |
-
}
|
227 |
-
]
|
228 |
-
}
|
229 |
-
```
|
230 |
-
|
231 |
-
#### Generate Post
|
232 |
-
- **POST** `/api/posts/generate`
|
233 |
-
- **Description**: Generate a new post using AI
|
234 |
-
- **Request Body**:
|
235 |
-
```json
|
236 |
-
{
|
237 |
-
"user_id": "string"
|
238 |
-
}
|
239 |
-
```
|
240 |
-
- **Response**:
|
241 |
-
```json
|
242 |
-
{
|
243 |
-
"content": "string"
|
244 |
-
}
|
245 |
-
```
|
246 |
-
|
247 |
-
#### Create Post
|
248 |
-
- **POST** `/api/posts`
|
249 |
-
- **Description**: Create a new post
|
250 |
-
- **Request Body**:
|
251 |
-
```json
|
252 |
-
{
|
253 |
-
"social_account_id": "string",
|
254 |
-
"text_content": "string",
|
255 |
-
"image_content_url": "string",
|
256 |
-
"scheduled_at": "datetime"
|
257 |
-
}
|
258 |
-
```
|
259 |
-
- **Response**:
|
260 |
-
```json
|
261 |
-
{
|
262 |
-
"message": "Post created successfully",
|
263 |
-
"post": {
|
264 |
-
"id": "string",
|
265 |
-
"user_id": "string",
|
266 |
-
"social_account_id": "string",
|
267 |
-
"text_content": "string",
|
268 |
-
"image_content_url": "string",
|
269 |
-
"is_published": "boolean",
|
270 |
-
"created_at": "datetime",
|
271 |
-
"scheduled_at": "datetime"
|
272 |
-
}
|
273 |
-
}
|
274 |
-
```
|
275 |
-
|
276 |
-
#### Publish Post
|
277 |
-
- **POST** `/api/posts/{id}/publish`
|
278 |
-
- **Description**: Publish a post to social media
|
279 |
-
- **Response**:
|
280 |
-
```json
|
281 |
-
{
|
282 |
-
"message": "Post published successfully"
|
283 |
-
}
|
284 |
-
```
|
285 |
-
|
286 |
-
#### Delete Post
|
287 |
-
- **DELETE** `/api/posts/{id}`
|
288 |
-
- **Description**: Delete a post
|
289 |
-
- **Response**:
|
290 |
-
```json
|
291 |
-
{
|
292 |
-
"message": "Post deleted successfully"
|
293 |
-
}
|
294 |
-
```
|
295 |
-
|
296 |
-
### Schedules
|
297 |
-
|
298 |
-
#### Get All Schedules
|
299 |
-
- **GET** `/api/schedules`
|
300 |
-
- **Description**: Get all schedules for the current user
|
301 |
-
- **Response**:
|
302 |
-
```json
|
303 |
-
{
|
304 |
-
"schedules": [
|
305 |
-
{
|
306 |
-
"id": "string",
|
307 |
-
"social_account_id": "string",
|
308 |
-
"schedule_time": "string",
|
309 |
-
"adjusted_time": "string",
|
310 |
-
"created_at": "datetime"
|
311 |
-
}
|
312 |
-
]
|
313 |
-
}
|
314 |
-
```
|
315 |
-
|
316 |
-
#### Create Schedule
|
317 |
-
- **POST** `/api/schedules`
|
318 |
-
- **Description**: Create a new schedule
|
319 |
-
- **Request Body**:
|
320 |
-
```json
|
321 |
-
{
|
322 |
-
"social_account_id": "string",
|
323 |
-
"schedule_time": "string", // Format: "Monday 18:00"
|
324 |
-
"days": ["string"] // Array of days
|
325 |
-
}
|
326 |
-
```
|
327 |
-
- **Response**:
|
328 |
-
```json
|
329 |
-
{
|
330 |
-
"message": "Schedule created successfully",
|
331 |
-
"schedule": {
|
332 |
-
"id": "string",
|
333 |
-
"social_account_id": "string",
|
334 |
-
"schedule_time": "string",
|
335 |
-
"adjusted_time": "string",
|
336 |
-
"created_at": "datetime"
|
337 |
-
}
|
338 |
-
}
|
339 |
-
```
|
340 |
-
|
341 |
-
#### Delete Schedule
|
342 |
-
- **DELETE** `/api/schedules/{id}`
|
343 |
-
- **Description**: Delete a schedule
|
344 |
-
- **Response**:
|
345 |
-
```json
|
346 |
-
{
|
347 |
-
"message": "Schedule deleted successfully"
|
348 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
architecture_summary.md
DELETED
@@ -1,111 +0,0 @@
|
|
1 |
-
# Lin React Clone - Architecture Summary
|
2 |
-
|
3 |
-
## Project Overview
|
4 |
-
This document provides a comprehensive summary of the architecture for the React clone of the Lin application, which includes a Flask API backend and a React frontend.
|
5 |
-
|
6 |
-
## Current Status
|
7 |
-
The current Taipy-based Lin application has been thoroughly analyzed, and a complete architecture plan has been created for the React clone with the following components:
|
8 |
-
|
9 |
-
### Documentation Created
|
10 |
-
1. [Project Analysis](project_analysis.md) - Analysis of the current Taipy application
|
11 |
-
2. [README](README.md) - Overview of the React clone project
|
12 |
-
3. [Backend Structure](backend_structure.md) - Planned structure for the Flask API backend
|
13 |
-
4. [Frontend Structure](frontend_structure.md) - Planned structure for the React frontend
|
14 |
-
5. [API Design](api_design.md) - Detailed RESTful API endpoints
|
15 |
-
6. [Component Architecture](component_architecture.md) - React component hierarchy and design
|
16 |
-
7. [Backend Requirements](backend_requirements.md) - Technical requirements for the Flask backend
|
17 |
-
8. [Frontend Requirements](frontend_requirements.md) - Technical requirements for the React frontend
|
18 |
-
9. [Deployment Architecture](deployment_architecture.md) - Infrastructure and deployment plan
|
19 |
-
10. [Development Roadmap](development_roadmap.md) - Phased implementation plan
|
20 |
-
|
21 |
-
## Key Architectural Decisions
|
22 |
-
|
23 |
-
### Backend Architecture
|
24 |
-
- **Framework**: Flask for lightweight, flexible API development
|
25 |
-
- **Database**: Supabase (PostgreSQL-based) for data persistence
|
26 |
-
- **Authentication**: JWT-based authentication with secure token management
|
27 |
-
- **Scheduling**: APScheduler for task scheduling with conflict resolution
|
28 |
-
- **External Integrations**: LinkedIn API and Hugging Face API
|
29 |
-
- **Deployment**: Containerized deployment with horizontal scaling
|
30 |
-
|
31 |
-
### Frontend Architecture
|
32 |
-
- **Framework**: React with functional components and hooks
|
33 |
-
- **State Management**: Redux Toolkit for predictable state management
|
34 |
-
- **Routing**: React Router for client-side routing
|
35 |
-
- **UI Components**: Material-UI for consistent, accessible components
|
36 |
-
- **Form Handling**: Formik with Yup for form validation
|
37 |
-
- **API Communication**: Axios with interceptors for HTTP requests
|
38 |
-
- **Deployment**: Static hosting with CDN for optimal performance
|
39 |
-
|
40 |
-
### Data Flow
|
41 |
-
1. User interacts with React frontend
|
42 |
-
2. Frontend makes API calls to Flask backend
|
43 |
-
3. Backend processes requests and interacts with Supabase database
|
44 |
-
4. Backend integrates with external APIs (LinkedIn, Hugging Face)
|
45 |
-
5. Backend returns data to frontend
|
46 |
-
6. Frontend updates UI based on response
|
47 |
-
|
48 |
-
### Security Considerations
|
49 |
-
- JWT tokens for secure authentication
|
50 |
-
- HTTPS encryption for all communications
|
51 |
-
- Input validation and sanitization
|
52 |
-
- CORS policy configuration
|
53 |
-
- Secure storage of sensitive data
|
54 |
-
- Rate limiting for API endpoints
|
55 |
-
|
56 |
-
## Implementation Roadmap
|
57 |
-
|
58 |
-
The development is planned in 6 phases over 12 weeks:
|
59 |
-
|
60 |
-
1. **Foundation** (Weeks 1-2): Project setup, authentication
|
61 |
-
2. **Core Features** (Weeks 3-4): Source and account management
|
62 |
-
3. **Content Management** (Weeks 5-6): Post creation and publishing
|
63 |
-
4. **Scheduling System** (Weeks 7-8): Automated scheduling
|
64 |
-
5. **Advanced Features** (Weeks 9-10): Analytics and optimization
|
65 |
-
6. **Testing and Deployment** (Weeks 11-12): Production readiness
|
66 |
-
|
67 |
-
## Technology Stack
|
68 |
-
|
69 |
-
### Backend
|
70 |
-
- Flask (Python web framework)
|
71 |
-
- Supabase (Database and authentication)
|
72 |
-
- APScheduler (Task scheduling)
|
73 |
-
- requests (HTTP library)
|
74 |
-
- python-dotenv (Environment management)
|
75 |
-
|
76 |
-
### Frontend
|
77 |
-
- React (JavaScript library)
|
78 |
-
- Redux Toolkit (State management)
|
79 |
-
- Material-UI (UI components)
|
80 |
-
- React Router (Routing)
|
81 |
-
- Axios (HTTP client)
|
82 |
-
- Formik/Yup (Form handling)
|
83 |
-
|
84 |
-
## Deployment Architecture
|
85 |
-
|
86 |
-
The application will be deployed with:
|
87 |
-
- CDN for frontend assets
|
88 |
-
- Load balancer for backend API
|
89 |
-
- Containerized Flask applications
|
90 |
-
- Supabase for database and authentication
|
91 |
-
- Monitoring and logging infrastructure
|
92 |
-
- CI/CD pipeline for automated deployment
|
93 |
-
|
94 |
-
## Next Steps
|
95 |
-
|
96 |
-
To begin implementation, the following actions are recommended:
|
97 |
-
|
98 |
-
1. Set up development environments for both frontend and backend
|
99 |
-
2. Create GitHub repositories for version control
|
100 |
-
3. Implement the foundation phase (authentication, project structure)
|
101 |
-
4. Begin CI/CD pipeline setup
|
102 |
-
5. Start frontend and backend development in parallel
|
103 |
-
|
104 |
-
## Success Criteria
|
105 |
-
|
106 |
-
The success of this architecture will be measured by:
|
107 |
-
- Performance (API response times < 500ms)
|
108 |
-
- Reliability (99.9% uptime)
|
109 |
-
- Scalability (support for 10,000+ users)
|
110 |
-
- User satisfaction (intuitive UI/UX)
|
111 |
-
- Maintainability (modular, well-documented code)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/TASK_SCHEDULING_EVOLUTION.md
DELETED
@@ -1,124 +0,0 @@
|
|
1 |
-
# Task Scheduling Evolution: From APScheduler to Celery
|
2 |
-
|
3 |
-
## Overview
|
4 |
-
|
5 |
-
This document describes the evolution of the task scheduling system in the Lin application from using APScheduler to using Celery. This change was made to improve scalability, reliability, and maintainability of the scheduling system.
|
6 |
-
|
7 |
-
## Previous Implementation (APScheduler)
|
8 |
-
|
9 |
-
The previous implementation used APScheduler (Advanced Python Scheduler) for managing scheduled tasks. While APScheduler is a powerful library, it has some limitations in production environments:
|
10 |
-
|
11 |
-
1. **Single Process**: APScheduler runs within the same process as the Flask application, which can lead to resource contention.
|
12 |
-
2. **Limited Scalability**: Difficult to scale across multiple instances or servers.
|
13 |
-
3. **Persistence Issues**: While APScheduler supports job persistence, it's not as robust as dedicated task queues.
|
14 |
-
4. **Monitoring**: Limited built-in monitoring and management capabilities.
|
15 |
-
|
16 |
-
### Key Components of APScheduler Implementation:
|
17 |
-
|
18 |
-
- `backend/scheduler/task_scheduler.py`: Main scheduler implementation
|
19 |
-
- `backend/app.py`: Scheduler initialization in Flask app
|
20 |
-
- Jobs were stored in memory and periodically reloaded from the database
|
21 |
-
|
22 |
-
## New Implementation (Celery)
|
23 |
-
|
24 |
-
The new implementation uses Celery, a distributed task queue, which provides several advantages:
|
25 |
-
|
26 |
-
1. **Distributed Processing**: Tasks can be distributed across multiple workers and machines.
|
27 |
-
2. **Persistence**: Tasks are stored in a message broker (Redis) for reliability.
|
28 |
-
3. **Scalability**: Easy to scale by adding more workers.
|
29 |
-
4. **Monitoring**: Built-in monitoring tools and integration with Flower for web-based monitoring.
|
30 |
-
5. **Fault Tolerance**: Workers can be restarted without losing tasks.
|
31 |
-
6. **Flexible Routing**: Tasks can be routed to specific queues for better resource management.
|
32 |
-
|
33 |
-
### Key Components of Celery Implementation:
|
34 |
-
|
35 |
-
- `backend/celery_app.py`: Main Celery application configuration
|
36 |
-
- `backend/celery_tasks/`: Directory containing Celery tasks
|
37 |
-
- `content_tasks.py`: Tasks for content generation and publishing
|
38 |
-
- `scheduler.py`: Scheduler functions for task management
|
39 |
-
- `schedule_loader.py`: Task for loading schedules from database
|
40 |
-
- `backend/celery_beat_config.py`: Celery Beat configuration for periodic tasks
|
41 |
-
- `backend/scheduler/task_scheduler.py`: Updated scheduler that works with Celery
|
42 |
-
|
43 |
-
### Celery Architecture
|
44 |
-
|
45 |
-
The new implementation follows this architecture:
|
46 |
-
|
47 |
-
```
|
48 |
-
[Flask App] --> [Redis Broker] --> [Celery Workers]
|
49 |
-
^
|
50 |
-
|
|
51 |
-
[Celery Beat]
|
52 |
-
```
|
53 |
-
|
54 |
-
1. **Flask App**: The main web application that can trigger tasks
|
55 |
-
2. **Redis Broker**: Message broker that stores tasks and results
|
56 |
-
3. **Celery Workers**: Processes that execute tasks
|
57 |
-
4. **Celery Beat**: Scheduler that triggers periodic tasks
|
58 |
-
|
59 |
-
### Task Types
|
60 |
-
|
61 |
-
1. **Content Generation Task**: Generates content for scheduled posts
|
62 |
-
2. **Post Publishing Task**: Publishes posts to LinkedIn
|
63 |
-
3. **Schedule Loader Task**: Periodically loads schedules from the database and updates Celery Beat
|
64 |
-
|
65 |
-
### Configuration
|
66 |
-
|
67 |
-
The Celery implementation is configured through environment variables:
|
68 |
-
|
69 |
-
- `CELERY_BROKER_URL`: URL for the message broker (default: redis://localhost:6379/0)
|
70 |
-
- `CELERY_RESULT_BACKEND`: URL for the result backend (default: redis://localhost:6379/0)
|
71 |
-
|
72 |
-
### Running the System
|
73 |
-
|
74 |
-
To run the new Celery-based system:
|
75 |
-
|
76 |
-
1. **Start Redis Server**:
|
77 |
-
```bash
|
78 |
-
redis-server
|
79 |
-
```
|
80 |
-
|
81 |
-
2. **Start Celery Workers**:
|
82 |
-
```bash
|
83 |
-
cd backend
|
84 |
-
celery -A celery_app worker --loglevel=info
|
85 |
-
```
|
86 |
-
|
87 |
-
3. **Start Celery Beat (Scheduler)**:
|
88 |
-
```bash
|
89 |
-
cd backend
|
90 |
-
celery -A celery_beat_config beat --loglevel=info
|
91 |
-
```
|
92 |
-
|
93 |
-
4. **Start Flask Application**:
|
94 |
-
```bash
|
95 |
-
cd backend
|
96 |
-
python app.py
|
97 |
-
```
|
98 |
-
|
99 |
-
### Benefits of the Migration
|
100 |
-
|
101 |
-
1. **Improved Reliability**: Tasks are persisted in Redis and survive worker restarts
|
102 |
-
2. **Better Scalability**: Can easily add more workers to handle increased load
|
103 |
-
3. **Enhanced Monitoring**: Can use Flower to monitor tasks and workers
|
104 |
-
4. **Separation of Concerns**: Web application and task processing are now separate processes
|
105 |
-
5. **Fault Tolerance**: If one worker fails, others can continue processing tasks
|
106 |
-
6. **Flexible Deployment**: Workers can be deployed on different machines
|
107 |
-
|
108 |
-
### Migration Process
|
109 |
-
|
110 |
-
The migration was done in a way that maintains backward compatibility:
|
111 |
-
|
112 |
-
1. **New Components Added**: All Celery components were added without removing the old ones
|
113 |
-
2. **Configuration Update**: The Flask app was updated to use Celery instead of APScheduler
|
114 |
-
3. **Task Refactoring**: Existing task logic was refactored into Celery tasks
|
115 |
-
4. **Testing**: The new system was tested to ensure it works correctly
|
116 |
-
5. **Documentation**: This document was created to explain the changes
|
117 |
-
|
118 |
-
### Future Improvements
|
119 |
-
|
120 |
-
1. **Add Flower for Monitoring**: Integrate Flower for web-based task monitoring
|
121 |
-
2. **Implement Retry Logic**: Add more sophisticated retry logic for failed tasks
|
122 |
-
3. **Add Task Priorities**: Implement task priorities for better resource management
|
123 |
-
4. **Enhance Error Handling**: Improve error handling and logging for tasks
|
124 |
-
5. **Add Task Chaining**: Use Celery's chaining capabilities for complex workflows
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/api/posts.py
CHANGED
@@ -1,6 +1,8 @@
|
|
|
|
1 |
import codecs
|
2 |
import uuid
|
3 |
-
|
|
|
4 |
from flask_jwt_extended import jwt_required, get_jwt_identity
|
5 |
from backend.services.content_service import ContentService
|
6 |
from backend.services.linkedin_service import LinkedInService
|
@@ -98,27 +100,6 @@ def get_posts():
|
|
98 |
response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000')
|
99 |
response_data.headers.add('Access-Control-Allow-Credentials', 'true')
|
100 |
return response_data, 500
|
101 |
-
|
102 |
-
# Add CORS headers explicitly
|
103 |
-
response_data = jsonify({
|
104 |
-
'success': True,
|
105 |
-
'posts': user_posts
|
106 |
-
})
|
107 |
-
response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000')
|
108 |
-
response_data.headers.add('Access-Control-Allow-Credentials', 'true')
|
109 |
-
return response_data, 200
|
110 |
-
|
111 |
-
except Exception as e:
|
112 |
-
error_message = str(e)
|
113 |
-
safe_log_message(f"Get posts error: {error_message}")
|
114 |
-
# Add CORS headers to error response
|
115 |
-
response_data = jsonify({
|
116 |
-
'success': False,
|
117 |
-
'message': 'An error occurred while fetching posts'
|
118 |
-
})
|
119 |
-
response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000')
|
120 |
-
response_data.headers.add('Access-Control-Allow-Credentials', 'true')
|
121 |
-
return response_data, 500
|
122 |
|
123 |
def _generate_post_task(user_id, job_id, job_store, hugging_key):
|
124 |
"""
|
@@ -270,10 +251,35 @@ def get_job_status(job_id):
|
|
270 |
# In a future update, we might save it to storage and return a URL
|
271 |
response_data['image_url'] = None
|
272 |
response_data['has_image_data'] = True # Flag to indicate image data exists
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
else:
|
274 |
-
# If it's
|
275 |
-
response_data['image_url'] =
|
276 |
-
response_data['has_image_data'] =
|
277 |
else:
|
278 |
response_data['content'] = job['result']
|
279 |
response_data['image_url'] = None
|
@@ -291,11 +297,46 @@ def get_job_status(job_id):
|
|
291 |
'message': f'An error occurred while fetching job status: {error_message}'
|
292 |
}), 500
|
293 |
|
294 |
-
@posts_bp.route('/', methods=['
|
295 |
-
@
|
296 |
-
def
|
297 |
-
"""
|
298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
|
300 |
@posts_bp.route('/publish-direct', methods=['OPTIONS'])
|
301 |
def handle_publish_direct_options():
|
|
|
1 |
+
import os
|
2 |
import codecs
|
3 |
import uuid
|
4 |
+
import base64
|
5 |
+
from flask import Blueprint, request, jsonify, current_app, send_file
|
6 |
from flask_jwt_extended import jwt_required, get_jwt_identity
|
7 |
from backend.services.content_service import ContentService
|
8 |
from backend.services.linkedin_service import LinkedInService
|
|
|
100 |
response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000')
|
101 |
response_data.headers.add('Access-Control-Allow-Credentials', 'true')
|
102 |
return response_data, 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
|
104 |
def _generate_post_task(user_id, job_id, job_store, hugging_key):
|
105 |
"""
|
|
|
251 |
# In a future update, we might save it to storage and return a URL
|
252 |
response_data['image_url'] = None
|
253 |
response_data['has_image_data'] = True # Flag to indicate image data exists
|
254 |
+
elif isinstance(image_data, dict):
|
255 |
+
# Handle the case where image_data is a dict from Gradio API
|
256 |
+
# The dict may contain 'path', 'url', or other keys
|
257 |
+
if image_data.get('url'):
|
258 |
+
response_data['image_url'] = image_data['url']
|
259 |
+
response_data['has_image_data'] = True
|
260 |
+
elif image_data.get('path'):
|
261 |
+
# If we have a path, we might need to serve it or convert it to a URL
|
262 |
+
# For now, we'll just indicate that image data exists
|
263 |
+
response_data['image_url'] = None
|
264 |
+
response_data['has_image_data'] = True
|
265 |
+
else:
|
266 |
+
response_data['image_url'] = None
|
267 |
+
response_data['has_image_data'] = image_data is not None
|
268 |
+
elif isinstance(image_data, str):
|
269 |
+
# Check if it's a local file path
|
270 |
+
if os.path.exists(image_data):
|
271 |
+
# Store the file path in job store for later retrieval
|
272 |
+
job['image_file_path'] = image_data
|
273 |
+
response_data['image_url'] = f"/api/posts/image/{job_id}" # API endpoint to serve the image
|
274 |
+
response_data['has_image_data'] = True
|
275 |
+
else:
|
276 |
+
# If it's a URL, use it directly
|
277 |
+
response_data['image_url'] = image_data
|
278 |
+
response_data['has_image_data'] = True
|
279 |
else:
|
280 |
+
# If it's None or other type
|
281 |
+
response_data['image_url'] = None
|
282 |
+
response_data['has_image_data'] = image_data is not None
|
283 |
else:
|
284 |
response_data['content'] = job['result']
|
285 |
response_data['image_url'] = None
|
|
|
297 |
'message': f'An error occurred while fetching job status: {error_message}'
|
298 |
}), 500
|
299 |
|
300 |
+
@posts_bp.route('/image/<job_id>', methods=['GET'])
|
301 |
+
@jwt_required()
|
302 |
+
def get_job_image(job_id):
|
303 |
+
"""
|
304 |
+
Serve image file for a completed job.
|
305 |
+
|
306 |
+
Path Parameters:
|
307 |
+
job_id (str): Job ID
|
308 |
+
|
309 |
+
Returns:
|
310 |
+
Image file
|
311 |
+
"""
|
312 |
+
try:
|
313 |
+
# Get job from store
|
314 |
+
job = current_app.job_store.get(job_id)
|
315 |
+
|
316 |
+
if not job:
|
317 |
+
return jsonify({
|
318 |
+
'success': False,
|
319 |
+
'message': 'Job not found'
|
320 |
+
}), 404
|
321 |
+
|
322 |
+
# Check if job has an image file path
|
323 |
+
image_file_path = job.get('image_file_path')
|
324 |
+
if not image_file_path or not os.path.exists(image_file_path):
|
325 |
+
return jsonify({
|
326 |
+
'success': False,
|
327 |
+
'message': 'Image not found'
|
328 |
+
}), 404
|
329 |
+
|
330 |
+
# Serve the image file
|
331 |
+
return send_file(image_file_path)
|
332 |
+
|
333 |
+
except Exception as e:
|
334 |
+
error_message = str(e)
|
335 |
+
safe_log_message(f"Get job image error: {error_message}")
|
336 |
+
return jsonify({
|
337 |
+
'success': False,
|
338 |
+
'message': f'An error occurred while fetching image: {error_message}'
|
339 |
+
}), 500
|
340 |
|
341 |
@posts_bp.route('/publish-direct', methods=['OPTIONS'])
|
342 |
def handle_publish_direct_options():
|
backend/app.py
CHANGED
@@ -2,6 +2,9 @@ import os
|
|
2 |
import sys
|
3 |
import locale
|
4 |
import logging
|
|
|
|
|
|
|
5 |
from flask import Flask, send_from_directory, request
|
6 |
from flask_cors import CORS
|
7 |
from flask_jwt_extended import JWTManager
|
@@ -101,11 +104,16 @@ def create_app():
|
|
101 |
"https://zelyanoth-lin-cbfcff2.hf.space"
|
102 |
]
|
103 |
|
|
|
104 |
if origin in allowed_origins:
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
|
110 |
return response
|
111 |
|
|
|
2 |
import sys
|
3 |
import locale
|
4 |
import logging
|
5 |
+
# Add the project root to the Python path
|
6 |
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
7 |
+
|
8 |
from flask import Flask, send_from_directory, request
|
9 |
from flask_cors import CORS
|
10 |
from flask_jwt_extended import JWTManager
|
|
|
104 |
"https://zelyanoth-lin-cbfcff2.hf.space"
|
105 |
]
|
106 |
|
107 |
+
# Only add CORS headers if they haven't been set by Flask-CORS already
|
108 |
if origin in allowed_origins:
|
109 |
+
if 'Access-Control-Allow-Origin' not in response.headers:
|
110 |
+
response.headers['Access-Control-Allow-Origin'] = origin
|
111 |
+
if 'Access-Control-Allow-Credentials' not in response.headers:
|
112 |
+
response.headers['Access-Control-Allow-Credentials'] = 'true'
|
113 |
+
if 'Access-Control-Allow-Methods' not in response.headers:
|
114 |
+
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
|
115 |
+
if 'Access-Control-Allow-Headers' not in response.headers:
|
116 |
+
response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With'
|
117 |
|
118 |
return response
|
119 |
|
backend/services/__init__.py
CHANGED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
# backend/services/__init__.py
|
2 |
+
# This file makes the services directory a Python package
|
backend/services/content_service.py
CHANGED
@@ -124,29 +124,35 @@ class ContentService:
|
|
124 |
api_name="/poster_linkedin"
|
125 |
)
|
126 |
|
127 |
-
#
|
128 |
-
#
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
# If JSON parsing fails, check if it's already a Python list/object
|
133 |
-
try:
|
134 |
-
# Try to evaluate as Python literal (safe for lists/dicts)
|
135 |
-
import ast
|
136 |
-
parsed_result = ast.literal_eval(result)
|
137 |
-
except (ValueError, SyntaxError):
|
138 |
-
# If that fails, treat the result as a plain string
|
139 |
-
parsed_result = [result]
|
140 |
-
|
141 |
-
# Extract the first element if it's a list
|
142 |
-
if isinstance(parsed_result, list):
|
143 |
-
generated_content = parsed_result[0] if parsed_result and parsed_result[0] is not None else "Generated content will appear here..."
|
144 |
-
# Extract the second element as image URL if it exists
|
145 |
-
image_data = parsed_result[1] if len(parsed_result) > 1 and parsed_result[1] is not None else None
|
146 |
else:
|
147 |
-
|
148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
# Validate, sanitize, and preserve formatting of the generated content
|
151 |
sanitized_content = self.sanitize_content_for_api(generated_content)
|
152 |
|
|
|
124 |
api_name="/poster_linkedin"
|
125 |
)
|
126 |
|
127 |
+
# Handle the case where result might be a tuple from Gradio
|
128 |
+
# The Gradio API returns a tuple with (content, image_data)
|
129 |
+
if isinstance(result, tuple) and len(result) >= 2:
|
130 |
+
generated_content = result[0] if result[0] is not None else "Generated content will appear here..."
|
131 |
+
image_data = result[1] if result[1] is not None else None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
else:
|
133 |
+
# Parse the result (assuming it returns a list with content as first element)
|
134 |
+
# First try to parse as JSON
|
135 |
+
try:
|
136 |
+
parsed_result = json.loads(result)
|
137 |
+
except json.JSONDecodeError:
|
138 |
+
# If JSON parsing fails, check if it's already a Python list/object
|
139 |
+
try:
|
140 |
+
# Try to evaluate as Python literal (safe for lists/dicts)
|
141 |
+
import ast
|
142 |
+
parsed_result = ast.literal_eval(result)
|
143 |
+
except (ValueError, SyntaxError):
|
144 |
+
# If that fails, treat the result as a plain string
|
145 |
+
parsed_result = [result]
|
146 |
|
147 |
+
# Extract the first element if it's a list
|
148 |
+
if isinstance(parsed_result, list):
|
149 |
+
generated_content = parsed_result[0] if parsed_result and parsed_result[0] is not None else "Generated content will appear here..."
|
150 |
+
# Extract the second element as image URL if it exists
|
151 |
+
image_data = parsed_result[1] if len(parsed_result) > 1 and parsed_result[1] is not None else None
|
152 |
+
else:
|
153 |
+
generated_content = str(parsed_result) if parsed_result is not None else "Generated content will appear here..."
|
154 |
+
image_data = None
|
155 |
+
|
156 |
# Validate, sanitize, and preserve formatting of the generated content
|
157 |
sanitized_content = self.sanitize_content_for_api(generated_content)
|
158 |
|
backend_requirements.md
DELETED
@@ -1,163 +0,0 @@
|
|
1 |
-
# Backend Requirements
|
2 |
-
|
3 |
-
## Overview
|
4 |
-
This document outlines the technical requirements for the Flask API backend of the Lin application.
|
5 |
-
|
6 |
-
## Python Dependencies
|
7 |
-
The backend will require the following Python packages:
|
8 |
-
|
9 |
-
### Core Dependencies
|
10 |
-
- Flask: Web framework
|
11 |
-
- Flask-CORS: Cross-Origin Resource Sharing support
|
12 |
-
- Flask-JWT-Extended: JWT token management
|
13 |
-
- Flask-SQLAlchemy: ORM for database interactions
|
14 |
-
- Flask-Migrate: Database migration support
|
15 |
-
- python-dotenv: Environment variable management
|
16 |
-
- requests: HTTP library for API calls
|
17 |
-
- requests-oauthlib: OAuth support
|
18 |
-
- apscheduler: Task scheduling
|
19 |
-
- supabase: Supabase client for database operations
|
20 |
-
- pandas: Data manipulation
|
21 |
-
- gradio-client: Hugging Face API client
|
22 |
-
|
23 |
-
### Development Dependencies
|
24 |
-
- pytest: Testing framework
|
25 |
-
- pytest-cov: Test coverage reporting
|
26 |
-
- flake8: Code linting
|
27 |
-
- black: Code formatting
|
28 |
-
|
29 |
-
## Environment Variables
|
30 |
-
The backend will require the following environment variables:
|
31 |
-
|
32 |
-
- SUPABASE_URL: Supabase project URL
|
33 |
-
- SUPABASE_KEY: Supabase API key
|
34 |
-
- CLIENT_ID: LinkedIn OAuth client ID
|
35 |
-
- CLIENT_SECRET: LinkedIn OAuth client secret
|
36 |
-
- REDIRECT_URL: LinkedIn OAuth redirect URL
|
37 |
-
- HUGGING_KEY: Hugging Face API key
|
38 |
-
- JWT_SECRET_KEY: Secret key for JWT token generation
|
39 |
-
- DATABASE_URL: Database connection string (if using PostgreSQL directly)
|
40 |
-
|
41 |
-
## Database Requirements
|
42 |
-
The application will use Supabase as the primary database, which is based on PostgreSQL. The following tables will be needed:
|
43 |
-
|
44 |
-
### Users
|
45 |
-
- id (UUID)
|
46 |
-
- email (string)
|
47 |
-
- password_hash (string)
|
48 |
-
- created_at (timestamp)
|
49 |
-
- email_confirmed_at (timestamp)
|
50 |
-
|
51 |
-
### Social_network
|
52 |
-
- id (UUID)
|
53 |
-
- user_id (UUID, foreign key to Users)
|
54 |
-
- social_network (string)
|
55 |
-
- account_name (string)
|
56 |
-
- token (string)
|
57 |
-
- sub (string)
|
58 |
-
- given_name (string)
|
59 |
-
- family_name (string)
|
60 |
-
- picture (string)
|
61 |
-
- created_at (timestamp)
|
62 |
-
|
63 |
-
### Source
|
64 |
-
- id (UUID)
|
65 |
-
- user_id (UUID, foreign key to Users)
|
66 |
-
- source (string)
|
67 |
-
- category (string)
|
68 |
-
- last_update (timestamp)
|
69 |
-
- created_at (timestamp)
|
70 |
-
|
71 |
-
### Post_content
|
72 |
-
- id (UUID)
|
73 |
-
- social_account_id (UUID, foreign key to Social_network)
|
74 |
-
- text_content (text)
|
75 |
-
- image_content_url (bytea or URL)
|
76 |
-
- is_published (boolean)
|
77 |
-
- sched (UUID)
|
78 |
-
- created_at (timestamp)
|
79 |
-
- scheduled_at (timestamp)
|
80 |
-
|
81 |
-
### Scheduling
|
82 |
-
- id (UUID)
|
83 |
-
- social_account_id (UUID, foreign key to Social_network)
|
84 |
-
- schedule_time (string)
|
85 |
-
- adjusted_time (string)
|
86 |
-
- created_at (timestamp)
|
87 |
-
|
88 |
-
## API Requirements
|
89 |
-
|
90 |
-
### Authentication
|
91 |
-
- JWT-based authentication
|
92 |
-
- Password hashing with bcrypt
|
93 |
-
- Email confirmation flow
|
94 |
-
- Password reset functionality
|
95 |
-
|
96 |
-
### Security
|
97 |
-
- CORS policy configuration
|
98 |
-
- Input validation and sanitization
|
99 |
-
- Rate limiting for API endpoints
|
100 |
-
- Secure headers implementation
|
101 |
-
|
102 |
-
### Error Handling
|
103 |
-
- Consistent error response format
|
104 |
-
- Proper HTTP status codes
|
105 |
-
- Logging of errors for debugging
|
106 |
-
- Validation error handling
|
107 |
-
|
108 |
-
## Integration Requirements
|
109 |
-
|
110 |
-
### LinkedIn API
|
111 |
-
- OAuth2 authentication flow
|
112 |
-
- Post creation and publishing
|
113 |
-
- User profile information retrieval
|
114 |
-
- Image upload support
|
115 |
-
|
116 |
-
### Hugging Face API
|
117 |
-
- Content generation using Gradio client
|
118 |
-
- Error handling for API failures
|
119 |
-
- Timeout handling for long-running requests
|
120 |
-
|
121 |
-
### Scheduling System
|
122 |
-
- APScheduler for task management
|
123 |
-
- Conflict resolution for overlapping schedules
|
124 |
-
- Automatic adjustment of schedule times
|
125 |
-
- Persistent storage of scheduled tasks
|
126 |
-
|
127 |
-
## Deployment Requirements
|
128 |
-
|
129 |
-
### Server
|
130 |
-
- Python 3.8+
|
131 |
-
- WSGI server (Gunicorn recommended)
|
132 |
-
- Reverse proxy (Nginx recommended)
|
133 |
-
- SSL certificate for HTTPS
|
134 |
-
|
135 |
-
### Scalability
|
136 |
-
- Stateless design for horizontal scaling
|
137 |
-
- Database connection pooling
|
138 |
-
- Caching strategy for frequently accessed data
|
139 |
-
- Background task processing for long-running operations
|
140 |
-
|
141 |
-
### Monitoring
|
142 |
-
- Logging configuration
|
143 |
-
- Health check endpoints
|
144 |
-
- Performance monitoring
|
145 |
-
- Error tracking integration
|
146 |
-
|
147 |
-
## Testing Requirements
|
148 |
-
|
149 |
-
### Unit Tests
|
150 |
-
- Model validation tests
|
151 |
-
- Service layer tests
|
152 |
-
- Utility function tests
|
153 |
-
|
154 |
-
### Integration Tests
|
155 |
-
- API endpoint tests
|
156 |
-
- Database integration tests
|
157 |
-
- External API integration tests
|
158 |
-
|
159 |
-
### Test Coverage
|
160 |
-
- Minimum 80% code coverage
|
161 |
-
- Testing of edge cases
|
162 |
-
- Mocking of external dependencies
|
163 |
-
- Continuous integration setup
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend_structure.md
DELETED
@@ -1,78 +0,0 @@
|
|
1 |
-
# Backend Structure Plan
|
2 |
-
|
3 |
-
## Directory Structure
|
4 |
-
```
|
5 |
-
backend/
|
6 |
-
├── app.py # Flask application entry point
|
7 |
-
├── config.py # Configuration settings
|
8 |
-
├── requirements.txt # Python dependencies
|
9 |
-
├── .env # Environment variables
|
10 |
-
├── models/ # Database models
|
11 |
-
│ ├── __init__.py
|
12 |
-
│ ├── user.py # User model
|
13 |
-
│ ├── social_account.py # Social media account model
|
14 |
-
│ ├── source.py # RSS source model
|
15 |
-
│ ├── post.py # Post content model
|
16 |
-
│ └── schedule.py # Scheduling model
|
17 |
-
├── api/ # API endpoints
|
18 |
-
│ ├── __init__.py
|
19 |
-
│ ├── auth.py # Authentication endpoints
|
20 |
-
│ ├── sources.py # Source management endpoints
|
21 |
-
│ ├── accounts.py # Social account endpoints
|
22 |
-
│ ├── posts.py # Post management endpoints
|
23 |
-
│ └── schedules.py # Scheduling endpoints
|
24 |
-
├── services/ # Business logic
|
25 |
-
│ ├── __init__.py
|
26 |
-
│ ├── auth_service.py # Authentication service
|
27 |
-
│ ├── linkedin_service.py# LinkedIn integration service
|
28 |
-
│ ├── content_service.py # Content generation service
|
29 |
-
│ └── schedule_service.py# Scheduling service
|
30 |
-
├── utils/ # Utility functions
|
31 |
-
│ ├── __init__.py
|
32 |
-
│ ├── database.py # Database connection
|
33 |
-
│ └── helpers.py # Helper functions
|
34 |
-
└── scheduler/ # Task scheduling
|
35 |
-
├── __init__.py
|
36 |
-
└── task_scheduler.py # Scheduling implementation
|
37 |
-
```
|
38 |
-
|
39 |
-
## Key Components
|
40 |
-
|
41 |
-
### app.py
|
42 |
-
- Flask application initialization
|
43 |
-
- Configuration loading
|
44 |
-
- Blueprint registration
|
45 |
-
- CORS setup
|
46 |
-
- Error handlers
|
47 |
-
|
48 |
-
### config.py
|
49 |
-
- Environment-based configuration
|
50 |
-
- Database settings
|
51 |
-
- API keys and secrets
|
52 |
-
- Scheduler settings
|
53 |
-
|
54 |
-
### models/
|
55 |
-
- SQLAlchemy models for all database entities
|
56 |
-
- Relationship definitions
|
57 |
-
- Validation logic
|
58 |
-
|
59 |
-
### api/
|
60 |
-
- RESTful endpoints for all features
|
61 |
-
- Request validation
|
62 |
-
- Response formatting
|
63 |
-
- Authentication middleware
|
64 |
-
|
65 |
-
### services/
|
66 |
-
- Business logic implementation
|
67 |
-
- External API integrations
|
68 |
-
- Data processing and transformation
|
69 |
-
|
70 |
-
### utils/
|
71 |
-
- Database connection management
|
72 |
-
- Helper functions for common operations
|
73 |
-
- Error handling utilities
|
74 |
-
|
75 |
-
### scheduler/
|
76 |
-
- APScheduler implementation
|
77 |
-
- Task scheduling and execution
|
78 |
-
- Conflict resolution
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
component_architecture.md
DELETED
@@ -1,237 +0,0 @@
|
|
1 |
-
# React Component Architecture
|
2 |
-
|
3 |
-
## Overview
|
4 |
-
This document outlines the component architecture for the React frontend of the Lin application. The components are organized hierarchically to promote reusability and maintainability.
|
5 |
-
|
6 |
-
## Component Hierarchy
|
7 |
-
|
8 |
-
### App Component
|
9 |
-
```
|
10 |
-
App
|
11 |
-
├── Header
|
12 |
-
├── Sidebar
|
13 |
-
├── Routes
|
14 |
-
│ ├── Login
|
15 |
-
│ │ ├── LoginForm
|
16 |
-
│ │ └── RegisterForm
|
17 |
-
│ ├── Register
|
18 |
-
│ │ ├── RegisterForm
|
19 |
-
│ │ └── LoginForm
|
20 |
-
│ ├── Dashboard
|
21 |
-
│ │ ├── SourceManager
|
22 |
-
│ │ │ ├── SourceList
|
23 |
-
│ │ │ └── AddSourceForm
|
24 |
-
│ │ ├── PostManager
|
25 |
-
│ │ │ ├── PostList
|
26 |
-
│ │ │ ├── PostGenerator
|
27 |
-
│ │ │ └── PostForm
|
28 |
-
│ │ └── Scheduler
|
29 |
-
│ │ ├── ScheduleList
|
30 |
-
│ │ └── ScheduleForm
|
31 |
-
│ ├── Sources
|
32 |
-
│ │ ├── SourceList
|
33 |
-
│ │ └── AddSourceForm
|
34 |
-
│ ├── Posts
|
35 |
-
│ │ ├── PostList
|
36 |
-
│ │ ├── PostGenerator
|
37 |
-
│ │ └── PostForm
|
38 |
-
│ └── Schedule
|
39 |
-
│ ├── ScheduleList
|
40 |
-
│ └── ScheduleForm
|
41 |
-
└── Footer
|
42 |
-
```
|
43 |
-
|
44 |
-
## Component Details
|
45 |
-
|
46 |
-
### App
|
47 |
-
- Root component that manages global state
|
48 |
-
- Handles routing between pages
|
49 |
-
- Manages authentication state
|
50 |
-
|
51 |
-
### Header
|
52 |
-
- Navigation bar at the top of the application
|
53 |
-
- Contains application title and user menu
|
54 |
-
- Shows current user information
|
55 |
-
- Provides logout functionality
|
56 |
-
|
57 |
-
### Sidebar
|
58 |
-
- Navigation menu on the left side
|
59 |
-
- Links to main sections (Dashboard, Sources, Posts, Schedule)
|
60 |
-
- Responsive design for mobile devices
|
61 |
-
|
62 |
-
### Login
|
63 |
-
- Page for user authentication
|
64 |
-
- Contains LoginForm component
|
65 |
-
- Provides link to registration page
|
66 |
-
|
67 |
-
### LoginForm
|
68 |
-
- Form for user login
|
69 |
-
- Email and password fields
|
70 |
-
- Submit button
|
71 |
-
- Validation and error handling
|
72 |
-
|
73 |
-
### Register
|
74 |
-
- Page for user registration
|
75 |
-
- Contains RegisterForm component
|
76 |
-
- Provides link to login page
|
77 |
-
|
78 |
-
### RegisterForm
|
79 |
-
- Form for user registration
|
80 |
-
- Email, password, and confirm password fields
|
81 |
-
- Submit button
|
82 |
-
- Validation and error handling
|
83 |
-
|
84 |
-
### Dashboard
|
85 |
-
- Main dashboard page
|
86 |
-
- Overview of all features
|
87 |
-
- Quick access to main functions
|
88 |
-
- Summary statistics
|
89 |
-
|
90 |
-
### SourceManager
|
91 |
-
- Component for managing RSS sources
|
92 |
-
- Lists existing sources
|
93 |
-
- Provides form to add new sources
|
94 |
-
- Allows deletion of sources
|
95 |
-
|
96 |
-
### SourceList
|
97 |
-
- Displays list of sources in a table
|
98 |
-
- Shows source URL and category
|
99 |
-
- Provides delete functionality for each source
|
100 |
-
- Responsive design for different screen sizes
|
101 |
-
|
102 |
-
### AddSourceForm
|
103 |
-
- Form for adding new sources
|
104 |
-
- Source URL input field
|
105 |
-
- Submit button
|
106 |
-
- Validation and error handling
|
107 |
-
|
108 |
-
### PostManager
|
109 |
-
- Component for managing posts
|
110 |
-
- Lists existing posts
|
111 |
-
- Provides post generation functionality
|
112 |
-
- Allows creation and publishing of posts
|
113 |
-
|
114 |
-
### PostList
|
115 |
-
- Displays list of posts in a table
|
116 |
-
- Shows post content and status
|
117 |
-
- Provides publish and delete functionality for each post
|
118 |
-
- Filter by published status
|
119 |
-
|
120 |
-
### PostGenerator
|
121 |
-
- Component for AI-powered post generation
|
122 |
-
- Button to trigger generation
|
123 |
-
- Display area for generated content
|
124 |
-
- Ability to edit generated content
|
125 |
-
|
126 |
-
### PostForm
|
127 |
-
- Form for creating new posts
|
128 |
-
- Text content input (textarea)
|
129 |
-
- Image upload functionality
|
130 |
-
- Schedule posting option
|
131 |
-
- Submit button
|
132 |
-
|
133 |
-
### Scheduler
|
134 |
-
- Component for managing post schedules
|
135 |
-
- Lists existing schedules
|
136 |
-
- Provides form to create new schedules
|
137 |
-
|
138 |
-
### ScheduleList
|
139 |
-
- Displays list of schedules in a table
|
140 |
-
- Shows schedule time and associated account
|
141 |
-
- Provides delete functionality for each schedule
|
142 |
-
|
143 |
-
### ScheduleForm
|
144 |
-
- Form for creating new schedules
|
145 |
-
- Day selection (multiple days)
|
146 |
-
- Time selection (hour and minute)
|
147 |
-
- Account selection
|
148 |
-
- Submit button
|
149 |
-
|
150 |
-
### Footer
|
151 |
-
- Footer component at the bottom of the application
|
152 |
-
- Contains copyright information
|
153 |
-
- Links to documentation or support
|
154 |
-
|
155 |
-
## State Management
|
156 |
-
|
157 |
-
### Global State (Redux Store)
|
158 |
-
- User authentication state
|
159 |
-
- Current user information
|
160 |
-
- Social media accounts
|
161 |
-
- Sources
|
162 |
-
- Posts
|
163 |
-
- Schedules
|
164 |
-
|
165 |
-
### Component State
|
166 |
-
- Form input values
|
167 |
-
- Loading states
|
168 |
-
- Error messages
|
169 |
-
- UI-specific state (e.g., open/closed modals)
|
170 |
-
|
171 |
-
## Data Flow
|
172 |
-
|
173 |
-
1. **Authentication Flow**
|
174 |
-
- User submits login form
|
175 |
-
- LoginForm calls authService.login()
|
176 |
-
- authService makes API call to /api/auth/login
|
177 |
-
- API returns JWT token
|
178 |
-
- Token is stored in localStorage
|
179 |
-
- User state is updated in Redux store
|
180 |
-
- User is redirected to dashboard
|
181 |
-
|
182 |
-
2. **Source Management Flow**
|
183 |
-
- User submits AddSourceForm
|
184 |
-
- AddSourceForm calls sourceService.addSource()
|
185 |
-
- sourceService makes API call to /api/sources
|
186 |
-
- API returns new source data
|
187 |
-
- Source is added to Redux store
|
188 |
-
- SourceList is automatically updated
|
189 |
-
|
190 |
-
3. **Post Management Flow**
|
191 |
-
- User clicks "Generate Post" button
|
192 |
-
- PostGenerator calls postService.generatePost()
|
193 |
-
- postService makes API call to /api/posts/generate
|
194 |
-
- API returns generated content
|
195 |
-
- Content is displayed in PostGenerator
|
196 |
-
- User can edit content and submit PostForm
|
197 |
-
- PostForm calls postService.createPost()
|
198 |
-
- postService makes API call to /api/posts
|
199 |
-
- API returns new post data
|
200 |
-
- Post is added to Redux store
|
201 |
-
- PostList is automatically updated
|
202 |
-
|
203 |
-
4. **Scheduling Flow**
|
204 |
-
- User submits ScheduleForm
|
205 |
-
- ScheduleForm calls scheduleService.createSchedule()
|
206 |
-
- scheduleService makes API call to /api/schedules
|
207 |
-
- API returns new schedule data
|
208 |
-
- Schedule is added to Redux store
|
209 |
-
- ScheduleList is automatically updated
|
210 |
-
|
211 |
-
## Styling
|
212 |
-
|
213 |
-
### CSS Strategy
|
214 |
-
- CSS Modules for component-specific styles
|
215 |
-
- Global CSS variables for consistent theming
|
216 |
-
- Responsive design with media queries
|
217 |
-
- Mobile-first approach
|
218 |
-
|
219 |
-
### Theme
|
220 |
-
- Primary color: #910029 (Burgundy)
|
221 |
-
- Secondary color: #39404B (Dark Gray)
|
222 |
-
- Background color: #ECF4F7 (Light Blue)
|
223 |
-
- Text color: #2c3e50 (Dark Blue-Gray)
|
224 |
-
- Accent color: #800020 (Dark Burgundy)
|
225 |
-
|
226 |
-
## Responsive Design
|
227 |
-
|
228 |
-
### Breakpoints
|
229 |
-
- Mobile: 0px - 768px
|
230 |
-
- Tablet: 769px - 1024px
|
231 |
-
- Desktop: 1025px+
|
232 |
-
|
233 |
-
### Adaptations
|
234 |
-
- Sidebar becomes collapsible on mobile
|
235 |
-
- Tables become card-based layouts on mobile
|
236 |
-
- Forms stack vertically on mobile
|
237 |
-
- Font sizes adjust for different screen sizes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
deployment_architecture.md
DELETED
@@ -1,235 +0,0 @@
|
|
1 |
-
# Deployment Architecture
|
2 |
-
|
3 |
-
## Overview
|
4 |
-
This document outlines the deployment architecture for the Lin application, including both the React frontend and Flask API backend.
|
5 |
-
|
6 |
-
## Architecture Diagram
|
7 |
-
|
8 |
-
```mermaid
|
9 |
-
graph TD
|
10 |
-
A[Client Browser] --> B[CDN - Frontend Assets]
|
11 |
-
A --> C[Load Balancer]
|
12 |
-
C --> D[API Gateway]
|
13 |
-
D --> E[Flask API Server 1]
|
14 |
-
D --> F[Flask API Server 2]
|
15 |
-
D --> G[Flask API Server N]
|
16 |
-
E --> H[Supabase Database]
|
17 |
-
F --> H
|
18 |
-
G --> H
|
19 |
-
H --> I[Supabase Auth]
|
20 |
-
H --> J[Supabase Storage]
|
21 |
-
E --> K[External APIs]
|
22 |
-
F --> K
|
23 |
-
G --> K
|
24 |
-
K --> L[LinkedIn API]
|
25 |
-
K --> M[Hugging Face API]
|
26 |
-
```
|
27 |
-
|
28 |
-
## Components
|
29 |
-
|
30 |
-
### Client Layer
|
31 |
-
- Web browsers (desktop and mobile)
|
32 |
-
- Mobile applications (future consideration)
|
33 |
-
- API consumers (third-party integrations)
|
34 |
-
|
35 |
-
### Frontend Layer
|
36 |
-
- React application hosted on CDN
|
37 |
-
- Static assets (HTML, CSS, JavaScript, images)
|
38 |
-
- Client-side routing
|
39 |
-
- Browser-based caching
|
40 |
-
|
41 |
-
### API Layer
|
42 |
-
- Load balancer for traffic distribution
|
43 |
-
- API gateway for request routing
|
44 |
-
- Multiple Flask API server instances
|
45 |
-
- Horizontal scaling capabilities
|
46 |
-
|
47 |
-
### Backend Services Layer
|
48 |
-
- Supabase as the primary database
|
49 |
-
- Supabase Auth for user authentication
|
50 |
-
- Supabase Storage for file storage
|
51 |
-
- External API integrations
|
52 |
-
|
53 |
-
### External Services
|
54 |
-
- LinkedIn API for social media integration
|
55 |
-
- Hugging Face API for content generation
|
56 |
-
- Email service for user notifications
|
57 |
-
|
58 |
-
## Deployment Environments
|
59 |
-
|
60 |
-
### Development
|
61 |
-
- Local development environments
|
62 |
-
- Development database with sample data
|
63 |
-
- Debugging tools enabled
|
64 |
-
- Hot reloading for frontend development
|
65 |
-
|
66 |
-
### Staging
|
67 |
-
- Pre-production environment
|
68 |
-
- Mirror of production configuration
|
69 |
-
- Testing of new features
|
70 |
-
- Performance testing
|
71 |
-
|
72 |
-
### Production
|
73 |
-
- Live environment for users
|
74 |
-
- High availability configuration
|
75 |
-
- Monitoring and alerting
|
76 |
-
- Backup and disaster recovery
|
77 |
-
|
78 |
-
## Infrastructure Requirements
|
79 |
-
|
80 |
-
### Frontend Hosting
|
81 |
-
- CDN for static asset delivery
|
82 |
-
- HTTPS support
|
83 |
-
- Custom domain configuration
|
84 |
-
- Cache invalidation strategy
|
85 |
-
|
86 |
-
### Backend Hosting
|
87 |
-
- Cloud hosting platform (AWS, Google Cloud, Azure)
|
88 |
-
- Container orchestration (Docker Swarm, Kubernetes)
|
89 |
-
- Auto-scaling groups
|
90 |
-
- Health monitoring
|
91 |
-
|
92 |
-
### Database
|
93 |
-
- Supabase project with production plan
|
94 |
-
- Database backups
|
95 |
-
- Point-in-time recovery
|
96 |
-
- Read replicas for scaling
|
97 |
-
|
98 |
-
### Networking
|
99 |
-
- SSL certificates for HTTPS
|
100 |
-
- DNS configuration
|
101 |
-
- Firewall rules
|
102 |
-
- DDoS protection
|
103 |
-
|
104 |
-
## Scalability
|
105 |
-
|
106 |
-
### Horizontal Scaling
|
107 |
-
- Multiple API server instances
|
108 |
-
- Load balancing across instances
|
109 |
-
- Stateless application design
|
110 |
-
- Shared database for consistency
|
111 |
-
|
112 |
-
### Vertical Scaling
|
113 |
-
- Increasing server resources (CPU, memory)
|
114 |
-
- Database scaling options
|
115 |
-
- CDN bandwidth scaling
|
116 |
-
|
117 |
-
### Auto-scaling
|
118 |
-
- CPU-based scaling policies
|
119 |
-
- Request-based scaling policies
|
120 |
-
- Minimum and maximum instance limits
|
121 |
-
- Scaling cooldown periods
|
122 |
-
|
123 |
-
## Security
|
124 |
-
|
125 |
-
### Network Security
|
126 |
-
- Firewall configuration
|
127 |
-
- Private networks for backend services
|
128 |
-
- SSL/TLS encryption
|
129 |
-
- DDoS protection
|
130 |
-
|
131 |
-
### Application Security
|
132 |
-
- Authentication and authorization
|
133 |
-
- Input validation and sanitization
|
134 |
-
- Secure headers
|
135 |
-
- CORS policy configuration
|
136 |
-
|
137 |
-
### Data Security
|
138 |
-
- Encryption at rest
|
139 |
-
- Encryption in transit
|
140 |
-
- Database access controls
|
141 |
-
- Regular security audits
|
142 |
-
|
143 |
-
## Monitoring and Logging
|
144 |
-
|
145 |
-
### Application Monitoring
|
146 |
-
- Uptime monitoring
|
147 |
-
- Performance metrics
|
148 |
-
- Error tracking
|
149 |
-
- Custom dashboards
|
150 |
-
|
151 |
-
### Infrastructure Monitoring
|
152 |
-
- Server health metrics
|
153 |
-
- Network performance
|
154 |
-
- Database performance
|
155 |
-
- Resource utilization
|
156 |
-
|
157 |
-
### Logging
|
158 |
-
- Centralized log management
|
159 |
-
- Log retention policies
|
160 |
-
- Log analysis tools
|
161 |
-
- Alerting based on log patterns
|
162 |
-
|
163 |
-
## Backup and Disaster Recovery
|
164 |
-
|
165 |
-
### Data Backup
|
166 |
-
- Automated database backups
|
167 |
-
- Backup retention policies
|
168 |
-
- Point-in-time recovery
|
169 |
-
- Cross-region replication
|
170 |
-
|
171 |
-
### Disaster Recovery
|
172 |
-
- Recovery time objectives (RTO)
|
173 |
-
- Recovery point objectives (RPO)
|
174 |
-
- Failover procedures
|
175 |
-
- Business continuity planning
|
176 |
-
|
177 |
-
## CI/CD Pipeline
|
178 |
-
|
179 |
-
### Continuous Integration
|
180 |
-
- Automated testing on pull requests
|
181 |
-
- Code quality checks
|
182 |
-
- Security scanning
|
183 |
-
- Build artifact generation
|
184 |
-
|
185 |
-
### Continuous Deployment
|
186 |
-
- Automated deployment to staging
|
187 |
-
- Manual approval for production
|
188 |
-
- Rollback capabilities
|
189 |
-
- Blue-green deployment strategy
|
190 |
-
|
191 |
-
### Environment Promotion
|
192 |
-
- Development to staging
|
193 |
-
- Staging to production
|
194 |
-
- Feature flag management
|
195 |
-
- A/B testing capabilities
|
196 |
-
|
197 |
-
## Cost Considerations
|
198 |
-
|
199 |
-
### Infrastructure Costs
|
200 |
-
- Cloud hosting fees
|
201 |
-
- CDN costs
|
202 |
-
- Database hosting
|
203 |
-
- External API usage
|
204 |
-
|
205 |
-
### Operational Costs
|
206 |
-
- Monitoring and logging tools
|
207 |
-
- Backup storage
|
208 |
-
- Support and maintenance
|
209 |
-
- Team productivity tools
|
210 |
-
|
211 |
-
### Optimization Strategies
|
212 |
-
- Resource right-sizing
|
213 |
-
- Caching strategies
|
214 |
-
- Content delivery optimization
|
215 |
-
- Usage-based scaling
|
216 |
-
|
217 |
-
## Maintenance
|
218 |
-
|
219 |
-
### Regular Maintenance
|
220 |
-
- Security updates
|
221 |
-
- Dependency updates
|
222 |
-
- Performance tuning
|
223 |
-
- Database maintenance
|
224 |
-
|
225 |
-
### Scheduled Downtime
|
226 |
-
- Maintenance windows
|
227 |
-
- Communication plan
|
228 |
-
- Rollback procedures
|
229 |
-
- Post-maintenance validation
|
230 |
-
|
231 |
-
### Incident Response
|
232 |
-
- Incident classification
|
233 |
-
- Escalation procedures
|
234 |
-
- Communication protocols
|
235 |
-
- Post-incident analysis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
development_roadmap.md
DELETED
@@ -1,312 +0,0 @@
|
|
1 |
-
# Development Roadmap
|
2 |
-
|
3 |
-
## Overview
|
4 |
-
This document outlines the development roadmap for creating the React clone of the Lin application with a Flask API backend.
|
5 |
-
|
6 |
-
## Phase 1: Foundation (Weeks 1-2)
|
7 |
-
|
8 |
-
### Goals
|
9 |
-
- Set up development environments
|
10 |
-
- Create project structure
|
11 |
-
- Implement basic authentication
|
12 |
-
- Establish API communication
|
13 |
-
|
14 |
-
### Tasks
|
15 |
-
|
16 |
-
#### Backend
|
17 |
-
- [ ] Set up Flask project structure
|
18 |
-
- [ ] Configure environment variables
|
19 |
-
- [ ] Implement database connection with Supabase
|
20 |
-
- [ ] Create user model and authentication endpoints
|
21 |
-
- [ ] Implement JWT token generation and validation
|
22 |
-
- [ ] Set up API documentation (Swagger/OpenAPI)
|
23 |
-
|
24 |
-
#### Frontend
|
25 |
-
- [ ] Set up React project with Create React App or Vite
|
26 |
-
- [ ] Configure routing with React Router
|
27 |
-
- [ ] Set up Redux store and basic state management
|
28 |
-
- [ ] Create authentication context
|
29 |
-
- [ ] Implement login and registration forms
|
30 |
-
- [ ] Set up API service layer
|
31 |
-
|
32 |
-
#### Integration
|
33 |
-
- [ ] Connect frontend to backend authentication API
|
34 |
-
- [ ] Implement token storage and management
|
35 |
-
- [ ] Create basic UI components
|
36 |
-
- [ ] Set up development environment documentation
|
37 |
-
|
38 |
-
### Deliverables
|
39 |
-
- Functional authentication system
|
40 |
-
- Basic project structure for both frontend and backend
|
41 |
-
- API documentation
|
42 |
-
- Development environment setup guide
|
43 |
-
|
44 |
-
## Phase 2: Core Features (Weeks 3-4)
|
45 |
-
|
46 |
-
### Goals
|
47 |
-
- Implement source management
|
48 |
-
- Implement social account management
|
49 |
-
- Create basic UI for core features
|
50 |
-
|
51 |
-
### Tasks
|
52 |
-
|
53 |
-
#### Backend
|
54 |
-
- [ ] Create source model and CRUD endpoints
|
55 |
-
- [ ] Create social account model and CRUD endpoints
|
56 |
-
- [ ] Implement RSS feed integration service
|
57 |
-
- [ ] Add validation and error handling
|
58 |
-
- [ ] Implement pagination for lists
|
59 |
-
|
60 |
-
#### Frontend
|
61 |
-
- [ ] Create dashboard layout
|
62 |
-
- [ ] Implement source management UI
|
63 |
-
- [ ] Implement social account management UI
|
64 |
-
- [ ] Add form validation and error handling
|
65 |
-
- [ ] Create reusable components for forms and lists
|
66 |
-
|
67 |
-
#### Integration
|
68 |
-
- [ ] Connect source management UI to backend API
|
69 |
-
- [ ] Connect social account management UI to backend API
|
70 |
-
- [ ] Implement loading states and user feedback
|
71 |
-
- [ ] Add responsive design for mobile devices
|
72 |
-
|
73 |
-
### Deliverables
|
74 |
-
- Source management functionality
|
75 |
-
- Social account management functionality
|
76 |
-
- Basic dashboard UI
|
77 |
-
- Responsive design implementation
|
78 |
-
|
79 |
-
## Phase 3: Content Management (Weeks 5-6)
|
80 |
-
|
81 |
-
### Goals
|
82 |
-
- Implement post creation and management
|
83 |
-
- Integrate AI content generation
|
84 |
-
- Implement post publishing to LinkedIn
|
85 |
-
|
86 |
-
### Tasks
|
87 |
-
|
88 |
-
#### Backend
|
89 |
-
- [ ] Create post model and CRUD endpoints
|
90 |
-
- [ ] Implement Hugging Face API integration
|
91 |
-
- [ ] Create content generation service
|
92 |
-
- [ ] Implement LinkedIn API integration
|
93 |
-
- [ ] Add image handling for posts
|
94 |
-
|
95 |
-
#### Frontend
|
96 |
-
- [ ] Create post management UI
|
97 |
-
- [ ] Implement post creation form
|
98 |
-
- [ ] Add AI content generation interface
|
99 |
-
- [ ] Create post preview functionality
|
100 |
-
- [ ] Implement image upload component
|
101 |
-
|
102 |
-
#### Integration
|
103 |
-
- [ ] Connect post management UI to backend API
|
104 |
-
- [ ] Integrate AI content generation
|
105 |
-
- [ ] Implement post publishing workflow
|
106 |
-
- [ ] Add real-time updates for post status
|
107 |
-
|
108 |
-
### Deliverables
|
109 |
-
- Post creation and management functionality
|
110 |
-
- AI content generation integration
|
111 |
-
- LinkedIn publishing capability
|
112 |
-
- Complete post workflow UI
|
113 |
-
|
114 |
-
## Phase 4: Scheduling System (Weeks 7-8)
|
115 |
-
|
116 |
-
### Goals
|
117 |
-
- Implement scheduling functionality
|
118 |
-
- Create scheduling UI
|
119 |
-
- Integrate task scheduler with post generation and publishing
|
120 |
-
|
121 |
-
### Tasks
|
122 |
-
|
123 |
-
#### Backend
|
124 |
-
- [ ] Create schedule model and CRUD endpoints
|
125 |
-
- [ ] Implement APScheduler integration
|
126 |
-
- [ ] Create scheduling service
|
127 |
-
- [ ] Implement conflict resolution logic
|
128 |
-
- [ ] Add recurring schedule support
|
129 |
-
|
130 |
-
#### Frontend
|
131 |
-
- [ ] Create scheduling UI
|
132 |
-
- [ ] Implement schedule creation form
|
133 |
-
- [ ] Add schedule visualization (calendar view)
|
134 |
-
- [ ] Create schedule management interface
|
135 |
-
- [ ] Add notifications for scheduled events
|
136 |
-
|
137 |
-
#### Integration
|
138 |
-
- [ ] Connect scheduling UI to backend API
|
139 |
-
- [ ] Implement automatic post generation based on schedule
|
140 |
-
- [ ] Implement automatic post publishing based on schedule
|
141 |
-
- [ ] Add schedule conflict detection and resolution
|
142 |
-
|
143 |
-
### Deliverables
|
144 |
-
- Scheduling functionality
|
145 |
-
- Calendar-based schedule visualization
|
146 |
-
- Automated post generation and publishing
|
147 |
-
- Schedule conflict management
|
148 |
-
|
149 |
-
## Phase 5: Advanced Features (Weeks 9-10)
|
150 |
-
|
151 |
-
### Goals
|
152 |
-
- Implement analytics and reporting
|
153 |
-
- Add advanced UI features
|
154 |
-
- Optimize performance
|
155 |
-
- Implement comprehensive testing
|
156 |
-
|
157 |
-
### Tasks
|
158 |
-
|
159 |
-
#### Backend
|
160 |
-
- [ ] Implement analytics data collection
|
161 |
-
- [ ] Create reporting endpoints
|
162 |
-
- [ ] Add caching for improved performance
|
163 |
-
- [ ] Implement advanced search and filtering
|
164 |
-
- [ ] Add data export functionality
|
165 |
-
|
166 |
-
#### Frontend
|
167 |
-
- [ ] Create analytics dashboard
|
168 |
-
- [ ] Implement data visualization components
|
169 |
-
- [ ] Add advanced filtering and search
|
170 |
-
- [ ] Implement data export features
|
171 |
-
- [ ] Add keyboard shortcuts and accessibility features
|
172 |
-
|
173 |
-
#### Integration
|
174 |
-
- [ ] Connect analytics dashboard to backend API
|
175 |
-
- [ ] Implement real-time data updates
|
176 |
-
- [ ] Add performance optimizations
|
177 |
-
- [ ] Implement comprehensive error handling
|
178 |
-
|
179 |
-
### Deliverables
|
180 |
-
- Analytics and reporting functionality
|
181 |
-
- Advanced UI features
|
182 |
-
- Performance optimizations
|
183 |
-
- Comprehensive testing suite
|
184 |
-
|
185 |
-
## Phase 6: Testing and Deployment (Weeks 11-12)
|
186 |
-
|
187 |
-
### Goals
|
188 |
-
- Complete comprehensive testing
|
189 |
-
- Prepare for production deployment
|
190 |
-
- Create deployment documentation
|
191 |
-
- Implement monitoring and logging
|
192 |
-
|
193 |
-
### Tasks
|
194 |
-
|
195 |
-
#### Backend
|
196 |
-
- [ ] Implement unit tests for all services
|
197 |
-
- [ ] Create integration tests for API endpoints
|
198 |
-
- [ ] Add load testing
|
199 |
-
- [ ] Implement logging and monitoring
|
200 |
-
- [ ] Create deployment scripts
|
201 |
-
|
202 |
-
#### Frontend
|
203 |
-
- [ ] Implement unit tests for components
|
204 |
-
- [ ] Create end-to-end tests
|
205 |
-
- [ ] Add performance testing
|
206 |
-
- [ ] Implement error tracking
|
207 |
-
- [ ] Create build and deployment scripts
|
208 |
-
|
209 |
-
#### Integration
|
210 |
-
- [ ] Conduct user acceptance testing
|
211 |
-
- [ ] Perform security testing
|
212 |
-
- [ ] Implement CI/CD pipeline
|
213 |
-
- [ ] Create production deployment guide
|
214 |
-
- [ ] Set up monitoring and alerting
|
215 |
-
|
216 |
-
### Deliverables
|
217 |
-
- Comprehensive test suite
|
218 |
-
- Production-ready deployment
|
219 |
-
- Monitoring and logging implementation
|
220 |
-
- Deployment documentation
|
221 |
-
|
222 |
-
## Risk Management
|
223 |
-
|
224 |
-
### Technical Risks
|
225 |
-
- LinkedIn API rate limiting
|
226 |
-
- Hugging Face API availability
|
227 |
-
- Database performance with large datasets
|
228 |
-
- Scheduling conflicts and edge cases
|
229 |
-
|
230 |
-
### Mitigation Strategies
|
231 |
-
- Implement caching and retry mechanisms
|
232 |
-
- Add fallback content generation methods
|
233 |
-
- Optimize database queries and indexing
|
234 |
-
- Thoroughly test scheduling edge cases
|
235 |
-
|
236 |
-
### Timeline Risks
|
237 |
-
- External API integration delays
|
238 |
-
- Complexity of scheduling system
|
239 |
-
- Performance optimization challenges
|
240 |
-
|
241 |
-
### Mitigation Strategies
|
242 |
-
- Build buffer time into schedule
|
243 |
-
- Implement incremental development approach
|
244 |
-
- Conduct regular performance testing
|
245 |
-
|
246 |
-
## Success Metrics
|
247 |
-
|
248 |
-
### Technical Metrics
|
249 |
-
- API response times under 500ms
|
250 |
-
- 99.9% uptime
|
251 |
-
- Less than 1% error rate
|
252 |
-
- Page load times under 2 seconds
|
253 |
-
|
254 |
-
### User Experience Metrics
|
255 |
-
- User satisfaction scores
|
256 |
-
- Task completion rates
|
257 |
-
- Feature adoption rates
|
258 |
-
- Support ticket volume
|
259 |
-
|
260 |
-
### Business Metrics
|
261 |
-
- User retention rate
|
262 |
-
- Daily/monthly active users
|
263 |
-
- Content generation volume
|
264 |
-
- Scheduled post success rate
|
265 |
-
|
266 |
-
## Resource Requirements
|
267 |
-
|
268 |
-
### Team Composition
|
269 |
-
- 1 Full-stack developer (primary)
|
270 |
-
- 1 Frontend developer (support)
|
271 |
-
- 1 Backend developer (support)
|
272 |
-
- 1 QA engineer
|
273 |
-
- 1 DevOps engineer
|
274 |
-
|
275 |
-
### Tools and Services
|
276 |
-
- Development environments (IDEs, databases)
|
277 |
-
- Testing tools (unit testing, end-to-end testing)
|
278 |
-
- CI/CD platform
|
279 |
-
- Monitoring and logging tools
|
280 |
-
- Project management software
|
281 |
-
|
282 |
-
## Milestones
|
283 |
-
|
284 |
-
### Milestone 1: Foundation Complete (End of Week 2)
|
285 |
-
- Authentication system functional
|
286 |
-
- Basic project structure established
|
287 |
-
- Development environments set up
|
288 |
-
|
289 |
-
### Milestone 2: Core Features Complete (End of Week 4)
|
290 |
-
- Source management implemented
|
291 |
-
- Social account management implemented
|
292 |
-
- Basic UI complete
|
293 |
-
|
294 |
-
### Milestone 3: Content Management Complete (End of Week 6)
|
295 |
-
- Post creation and management functional
|
296 |
-
- AI content generation integrated
|
297 |
-
- LinkedIn publishing working
|
298 |
-
|
299 |
-
### Milestone 4: Scheduling System Complete (End of Week 8)
|
300 |
-
- Scheduling functionality implemented
|
301 |
-
- Automated post generation and publishing
|
302 |
-
- Schedule conflict management
|
303 |
-
|
304 |
-
### Milestone 5: Advanced Features Complete (End of Week 10)
|
305 |
-
- Analytics and reporting functional
|
306 |
-
- Advanced UI features implemented
|
307 |
-
- Performance optimizations complete
|
308 |
-
|
309 |
-
### Milestone 6: Production Ready (End of Week 12)
|
310 |
-
- Comprehensive testing complete
|
311 |
-
- Production deployment ready
|
312 |
-
- Monitoring and logging implemented
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
frontend/src/pages/Posts.jsx
CHANGED
@@ -40,24 +40,13 @@ const Posts = () => {
|
|
40 |
try {
|
41 |
const result = await dispatch(generatePost()).unwrap();
|
42 |
|
43 |
-
// Handle
|
44 |
let content = result.content || 'Generated content will appear here...';
|
45 |
let image = null;
|
46 |
|
47 |
-
// If
|
48 |
-
if (
|
49 |
-
|
50 |
-
image = content[1] || null; // Second element might be image URL
|
51 |
-
}
|
52 |
-
// If result has image_url property (from backend)
|
53 |
-
else if (result.image_url) {
|
54 |
-
image = result.image_url;
|
55 |
-
}
|
56 |
-
// If result has has_image_data property, it means image data exists but is in bytes
|
57 |
-
else if (result.has_image_data) {
|
58 |
-
// For now, we'll just show a placeholder or message
|
59 |
-
// In a future update, we might fetch the image data separately
|
60 |
-
image = 'HAS_IMAGE_DATA_BUT_NOT_URL'; // Special marker
|
61 |
}
|
62 |
|
63 |
setPostContent(content);
|
@@ -94,7 +83,7 @@ const Posts = () => {
|
|
94 |
};
|
95 |
|
96 |
// Add image URL if available
|
97 |
-
if (postImage) {
|
98 |
publishData.image_content_url = postImage;
|
99 |
}
|
100 |
|
@@ -111,7 +100,7 @@ const Posts = () => {
|
|
111 |
};
|
112 |
|
113 |
// Add image URL if available
|
114 |
-
if (postImage) {
|
115 |
createData.image_content_url = postImage;
|
116 |
}
|
117 |
|
@@ -123,7 +112,6 @@ const Posts = () => {
|
|
123 |
setSelectedAccount('');
|
124 |
setPostContent('');
|
125 |
setPostImage(null);
|
126 |
-
setPostImage(null);
|
127 |
} catch (err) {
|
128 |
console.error('📝 [Posts] Failed to publish post:', err);
|
129 |
// Don't save to database if LinkedIn publish failed
|
|
|
40 |
try {
|
41 |
const result = await dispatch(generatePost()).unwrap();
|
42 |
|
43 |
+
// Handle the new structure of the result
|
44 |
let content = result.content || 'Generated content will appear here...';
|
45 |
let image = null;
|
46 |
|
47 |
+
// If result has image property (from updated backend/frontend)
|
48 |
+
if (result.image) {
|
49 |
+
image = result.image;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
|
52 |
setPostContent(content);
|
|
|
83 |
};
|
84 |
|
85 |
// Add image URL if available
|
86 |
+
if (postImage && postImage !== 'HAS_IMAGE_DATA_BUT_NOT_URL') {
|
87 |
publishData.image_content_url = postImage;
|
88 |
}
|
89 |
|
|
|
100 |
};
|
101 |
|
102 |
// Add image URL if available
|
103 |
+
if (postImage && postImage !== 'HAS_IMAGE_DATA_BUT_NOT_URL') {
|
104 |
createData.image_content_url = postImage;
|
105 |
}
|
106 |
|
|
|
112 |
setSelectedAccount('');
|
113 |
setPostContent('');
|
114 |
setPostImage(null);
|
|
|
115 |
} catch (err) {
|
116 |
console.error('📝 [Posts] Failed to publish post:', err);
|
117 |
// Don't save to database if LinkedIn publish failed
|
frontend/src/services/postService.js
CHANGED
@@ -40,12 +40,13 @@ class PostService {
|
|
40 |
const jobId = startResponse.data.job_id;
|
41 |
|
42 |
// Step 2: Poll for the result
|
43 |
-
const
|
44 |
|
45 |
// Ensure we return a default value if content is null/undefined
|
46 |
-
const finalContent =
|
|
|
47 |
|
48 |
-
return { data: { success: true, content: finalContent } };
|
49 |
} catch (error) {
|
50 |
if (import.meta.env.VITE_NODE_ENV === 'development') {
|
51 |
console.error('📝 [Post] Generate post error:', error.response?.data || error.message);
|
@@ -79,8 +80,22 @@ class PostService {
|
|
79 |
console.log('📝 [Post] Raw job data:', jobData);
|
80 |
}
|
81 |
|
82 |
-
// Extract content
|
83 |
-
let content =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
// If content is an array, take the first element
|
86 |
if (Array.isArray(content)) {
|
@@ -88,7 +103,10 @@ class PostService {
|
|
88 |
}
|
89 |
|
90 |
// Ensure we return the content even if it's an empty string
|
91 |
-
return
|
|
|
|
|
|
|
92 |
case 'failed':
|
93 |
throw new Error(jobData.error || 'Job failed');
|
94 |
case 'processing':
|
|
|
40 |
const jobId = startResponse.data.job_id;
|
41 |
|
42 |
// Step 2: Poll for the result
|
43 |
+
const generatedResult = await this.pollForJobResult(jobId);
|
44 |
|
45 |
// Ensure we return a default value if content is null/undefined
|
46 |
+
const finalContent = generatedResult.content !== undefined && generatedResult.content !== null ? generatedResult.content : "Generated content will appear here...";
|
47 |
+
const finalImage = generatedResult.image || null;
|
48 |
|
49 |
+
return { data: { success: true, content: finalContent, image: finalImage } };
|
50 |
} catch (error) {
|
51 |
if (import.meta.env.VITE_NODE_ENV === 'development') {
|
52 |
console.error('📝 [Post] Generate post error:', error.response?.data || error.message);
|
|
|
80 |
console.log('📝 [Post] Raw job data:', jobData);
|
81 |
}
|
82 |
|
83 |
+
// Extract content and image data from the job result
|
84 |
+
let content = '';
|
85 |
+
let imageData = null;
|
86 |
+
|
87 |
+
// Handle the new structure of the result
|
88 |
+
if (jobData.content !== undefined) {
|
89 |
+
content = jobData.content;
|
90 |
+
}
|
91 |
+
|
92 |
+
// Handle image data if it exists
|
93 |
+
if (jobData.image_url !== undefined && jobData.image_url !== null) {
|
94 |
+
imageData = jobData.image_url;
|
95 |
+
} else if (jobData.has_image_data) {
|
96 |
+
// Special marker for image data that exists but can't be displayed directly
|
97 |
+
imageData = 'HAS_IMAGE_DATA_BUT_NOT_URL';
|
98 |
+
}
|
99 |
|
100 |
// If content is an array, take the first element
|
101 |
if (Array.isArray(content)) {
|
|
|
103 |
}
|
104 |
|
105 |
// Ensure we return the content even if it's an empty string
|
106 |
+
return {
|
107 |
+
content: content !== undefined ? content : '',
|
108 |
+
image: imageData
|
109 |
+
};
|
110 |
case 'failed':
|
111 |
throw new Error(jobData.error || 'Job failed');
|
112 |
case 'processing':
|
frontend/src/store/reducers/postsSlice.js
CHANGED
@@ -125,6 +125,7 @@ const postsSlice = createSlice({
|
|
125 |
.addCase(generatePost.fulfilled, (state, action) => {
|
126 |
state.loading = false;
|
127 |
// We don't add generated content to the list, it's just for the form
|
|
|
128 |
})
|
129 |
.addCase(generatePost.rejected, (state, action) => {
|
130 |
state.loading = false;
|
|
|
125 |
.addCase(generatePost.fulfilled, (state, action) => {
|
126 |
state.loading = false;
|
127 |
// We don't add generated content to the list, it's just for the form
|
128 |
+
// But we do need to handle the result properly
|
129 |
})
|
130 |
.addCase(generatePost.rejected, (state, action) => {
|
131 |
state.loading = false;
|
frontend_requirements.md
DELETED
@@ -1,235 +0,0 @@
|
|
1 |
-
# Frontend Requirements
|
2 |
-
|
3 |
-
## Overview
|
4 |
-
This document outlines the technical requirements for the React frontend of the Lin application.
|
5 |
-
|
6 |
-
## Core Technologies
|
7 |
-
- React 18+
|
8 |
-
- React Router v6+
|
9 |
-
- Redux Toolkit for state management
|
10 |
-
- Axios for HTTP requests
|
11 |
-
- Material-UI (MUI) for UI components
|
12 |
-
- Formik for form handling
|
13 |
-
- Yup for form validation
|
14 |
-
|
15 |
-
## Development Tools
|
16 |
-
- Node.js 16+
|
17 |
-
- npm or yarn package manager
|
18 |
-
- Create React App or Vite for project setup
|
19 |
-
- ESLint for code linting
|
20 |
-
- Prettier for code formatting
|
21 |
-
- Jest and React Testing Library for testing
|
22 |
-
|
23 |
-
## Package Dependencies
|
24 |
-
|
25 |
-
### Core Dependencies
|
26 |
-
```json
|
27 |
-
{
|
28 |
-
"@mui/material": "^5.0.0",
|
29 |
-
"@mui/icons-material": "^5.0.0",
|
30 |
-
"@reduxjs/toolkit": "^1.8.0",
|
31 |
-
"axios": "^0.27.0",
|
32 |
-
"formik": "^2.2.9",
|
33 |
-
"react": "^18.0.0",
|
34 |
-
"react-dom": "^18.0.0",
|
35 |
-
"react-redux": "^8.0.0",
|
36 |
-
"react-router-dom": "^6.3.0",
|
37 |
-
"yup": "^0.32.11"
|
38 |
-
}
|
39 |
-
```
|
40 |
-
|
41 |
-
### Development Dependencies
|
42 |
-
```json
|
43 |
-
{
|
44 |
-
"@testing-library/jest-dom": "^5.16.4",
|
45 |
-
"@testing-library/react": "^13.3.0",
|
46 |
-
"@testing-library/user-event": "^14.2.0",
|
47 |
-
"eslint": "^8.18.0",
|
48 |
-
"prettier": "^2.7.1",
|
49 |
-
"jest": "^28.1.1"
|
50 |
-
}
|
51 |
-
```
|
52 |
-
|
53 |
-
## Browser Support
|
54 |
-
- Latest versions of Chrome, Firefox, Safari, and Edge
|
55 |
-
- Mobile browsers (iOS Safari, Chrome for Android)
|
56 |
-
- Responsive design for all screen sizes
|
57 |
-
|
58 |
-
## UI/UX Requirements
|
59 |
-
|
60 |
-
### Design System
|
61 |
-
- Consistent color palette based on brand colors
|
62 |
-
- Typography hierarchy with appropriate font sizes
|
63 |
-
- Spacing system using consistent units
|
64 |
-
- Component library with reusable UI elements
|
65 |
-
|
66 |
-
### Responsive Design
|
67 |
-
- Mobile-first approach
|
68 |
-
- Flexible grid system
|
69 |
-
- Adaptive components for different screen sizes
|
70 |
-
- Touch-friendly interface elements
|
71 |
-
|
72 |
-
### Accessibility
|
73 |
-
- WCAG 2.1 AA compliance
|
74 |
-
- Proper semantic HTML
|
75 |
-
- Keyboard navigation support
|
76 |
-
- Screen reader compatibility
|
77 |
-
- Color contrast ratios meeting accessibility standards
|
78 |
-
|
79 |
-
## State Management
|
80 |
-
|
81 |
-
### Redux Store Structure
|
82 |
-
```javascript
|
83 |
-
{
|
84 |
-
auth: {
|
85 |
-
user: object,
|
86 |
-
isAuthenticated: boolean,
|
87 |
-
loading: boolean,
|
88 |
-
error: string
|
89 |
-
},
|
90 |
-
sources: {
|
91 |
-
items: array,
|
92 |
-
loading: boolean,
|
93 |
-
error: string
|
94 |
-
},
|
95 |
-
posts: {
|
96 |
-
items: array,
|
97 |
-
loading: boolean,
|
98 |
-
error: string
|
99 |
-
},
|
100 |
-
accounts: {
|
101 |
-
items: array,
|
102 |
-
loading: boolean,
|
103 |
-
error: string
|
104 |
-
},
|
105 |
-
schedules: {
|
106 |
-
items: array,
|
107 |
-
loading: boolean,
|
108 |
-
error: string
|
109 |
-
}
|
110 |
-
}
|
111 |
-
```
|
112 |
-
|
113 |
-
### Actions and Reducers
|
114 |
-
- Async thunks for API calls
|
115 |
-
- Error handling in reducers
|
116 |
-
- Loading states for async operations
|
117 |
-
- Normalized data structure for efficient lookups
|
118 |
-
|
119 |
-
## Routing
|
120 |
-
|
121 |
-
### Routes Structure
|
122 |
-
- `/` - Dashboard (protected)
|
123 |
-
- `/login` - Login page (public)
|
124 |
-
- `/register` - Registration page (public)
|
125 |
-
- `/sources` - Source management (protected)
|
126 |
-
- `/posts` - Post management (protected)
|
127 |
-
- `/schedule` - Scheduling (protected)
|
128 |
-
- `/*` - 404 page
|
129 |
-
|
130 |
-
### Route Protection
|
131 |
-
- Authentication guard for protected routes
|
132 |
-
- Redirect logic for authenticated users
|
133 |
-
- Loading states during authentication checks
|
134 |
-
|
135 |
-
## API Integration
|
136 |
-
|
137 |
-
### Service Layer
|
138 |
-
- Axios instance with base URL configuration
|
139 |
-
- Request and response interceptors
|
140 |
-
- Error handling and transformation
|
141 |
-
- Authentication token management
|
142 |
-
|
143 |
-
### API Error Handling
|
144 |
-
- Network error detection
|
145 |
-
- HTTP error status handling
|
146 |
-
- User-friendly error messages
|
147 |
-
- Retry mechanism for failed requests
|
148 |
-
|
149 |
-
## Form Handling
|
150 |
-
|
151 |
-
### Form Libraries
|
152 |
-
- Formik for form state management
|
153 |
-
- Yup for form validation
|
154 |
-
- Custom validation rules
|
155 |
-
- Async validation support
|
156 |
-
|
157 |
-
### Form Components
|
158 |
-
- Reusable input components
|
159 |
-
- Validation error display
|
160 |
-
- Loading states during submission
|
161 |
-
- Success feedback after submission
|
162 |
-
|
163 |
-
## Testing Requirements
|
164 |
-
|
165 |
-
### Unit Tests
|
166 |
-
- Component rendering tests
|
167 |
-
- Redux action and reducer tests
|
168 |
-
- Utility function tests
|
169 |
-
- Hook tests
|
170 |
-
|
171 |
-
### Integration Tests
|
172 |
-
- Form submission flows
|
173 |
-
- API integration tests
|
174 |
-
- Routing tests
|
175 |
-
- Authentication flow tests
|
176 |
-
|
177 |
-
### Test Coverage
|
178 |
-
- Minimum 80% code coverage
|
179 |
-
- Testing of edge cases
|
180 |
-
- Mocking of external dependencies
|
181 |
-
- Continuous integration setup
|
182 |
-
|
183 |
-
## Performance Requirements
|
184 |
-
|
185 |
-
### Loading States
|
186 |
-
- Skeleton loaders for data fetching
|
187 |
-
- Progress indicators for long operations
|
188 |
-
- Optimistic updates where appropriate
|
189 |
-
- Error boundaries for component failures
|
190 |
-
|
191 |
-
### Bundle Optimization
|
192 |
-
- Code splitting for route-based chunks
|
193 |
-
- Lazy loading for non-critical components
|
194 |
-
- Image optimization and lazy loading
|
195 |
-
- Minification and compression
|
196 |
-
|
197 |
-
### Caching Strategy
|
198 |
-
- HTTP caching headers
|
199 |
-
- Client-side caching for static data
|
200 |
-
- Cache invalidation strategies
|
201 |
-
- Service worker implementation (optional)
|
202 |
-
|
203 |
-
## Security Considerations
|
204 |
-
|
205 |
-
### Client-Side Security
|
206 |
-
- XSS prevention through proper data escaping
|
207 |
-
- CSRF protection for forms
|
208 |
-
- Secure storage of authentication tokens
|
209 |
-
- Input validation and sanitization
|
210 |
-
|
211 |
-
### Authentication
|
212 |
-
- Secure token storage (HttpOnly cookies or secure localStorage)
|
213 |
-
- Token expiration and refresh mechanisms
|
214 |
-
- Logout functionality
|
215 |
-
- Session management
|
216 |
-
|
217 |
-
## Deployment Requirements
|
218 |
-
|
219 |
-
### Build Process
|
220 |
-
- Production build optimization
|
221 |
-
- Environment-specific configuration
|
222 |
-
- Asset fingerprinting for cache busting
|
223 |
-
- Source map generation for debugging
|
224 |
-
|
225 |
-
### Hosting
|
226 |
-
- Static file hosting (Netlify, Vercel, or similar)
|
227 |
-
- CDN integration for asset delivery
|
228 |
-
- SSL certificate for HTTPS
|
229 |
-
- Custom domain support
|
230 |
-
|
231 |
-
### CI/CD
|
232 |
-
- Automated testing on pull requests
|
233 |
-
- Automated deployment on merge to main branch
|
234 |
-
- Environment-specific deployments
|
235 |
-
- Rollback capabilities
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
frontend_structure.md
DELETED
@@ -1,93 +0,0 @@
|
|
1 |
-
# Frontend Structure Plan
|
2 |
-
|
3 |
-
## Directory Structure
|
4 |
-
```
|
5 |
-
frontend/
|
6 |
-
├── package.json # Project dependencies and scripts
|
7 |
-
├── public/ # Static assets
|
8 |
-
│ ├── index.html # Main HTML file
|
9 |
-
│ └── favicon.ico # Application icon
|
10 |
-
├── src/ # Source code
|
11 |
-
│ ├── index.js # Application entry point
|
12 |
-
│ ├── App.js # Root component
|
13 |
-
│ ├── App.css # Global styles
|
14 |
-
│ ├── components/ # Reusable components
|
15 |
-
│ │ ├── Header/ # Navigation header
|
16 |
-
│ │ ├── Sidebar/ # Navigation sidebar
|
17 |
-
│ │ ├── Auth/ # Authentication components
|
18 |
-
│ │ │ ├── LoginForm.js
|
19 |
-
│ │ │ └── RegisterForm.js
|
20 |
-
│ │ ├── Dashboard/ # Dashboard components
|
21 |
-
│ │ ├── Sources/ # Source management components
|
22 |
-
│ │ ├── Posts/ # Post management components
|
23 |
-
│ │ └── Scheduler/ # Scheduling components
|
24 |
-
│ ├── pages/ # Page components
|
25 |
-
│ │ ├── Home.js # Home page
|
26 |
-
│ │ ├── Login.js # Login page
|
27 |
-
│ │ ├── Register.js # Registration page
|
28 |
-
│ │ ├── Dashboard.js # Main dashboard
|
29 |
-
│ │ ├── Sources.js # Source management page
|
30 |
-
│ │ ├── Posts.js # Post management page
|
31 |
-
│ │ └── Schedule.js # Scheduling page
|
32 |
-
│ ├── services/ # API service layer
|
33 |
-
│ │ ├── api.js # Axios instance and interceptors
|
34 |
-
│ │ ├── authService.js # Authentication API calls
|
35 |
-
│ │ ├── sourceService.js# Source management API calls
|
36 |
-
│ │ ├── postService.js # Post management API calls
|
37 |
-
│ │ └── scheduleService.js# Scheduling API calls
|
38 |
-
│ ├── store/ # Redux store
|
39 |
-
│ │ ├── index.js # Store configuration
|
40 |
-
│ │ ├── actions/ # Action creators
|
41 |
-
│ │ └── reducers/ # Reducers
|
42 |
-
│ ├── hooks/ # Custom hooks
|
43 |
-
│ │ └── useAuth.js # Authentication hook
|
44 |
-
│ ├── utils/ # Utility functions
|
45 |
-
│ │ └── helpers.js # Helper functions
|
46 |
-
│ └── styles/ # CSS styles
|
47 |
-
│ ├── variables.css # CSS variables
|
48 |
-
│ ├── auth.css # Authentication styles
|
49 |
-
│ ├── dashboard.css # Dashboard styles
|
50 |
-
│ ├── sources.css # Source management styles
|
51 |
-
│ ├── posts.css # Post management styles
|
52 |
-
│ └── schedule.css # Scheduling styles
|
53 |
-
└── README.md # Frontend documentation
|
54 |
-
```
|
55 |
-
|
56 |
-
## Key Components
|
57 |
-
|
58 |
-
### App.js
|
59 |
-
- Main application component
|
60 |
-
- Routing configuration
|
61 |
-
- Authentication state management
|
62 |
-
- Layout structure (Header, Sidebar)
|
63 |
-
|
64 |
-
### Components
|
65 |
-
- Reusable UI components
|
66 |
-
- Presentational components with minimal logic
|
67 |
-
- Styled with CSS modules or styled-components
|
68 |
-
|
69 |
-
### Pages
|
70 |
-
- Page-level components that compose multiple components
|
71 |
-
- Route-specific logic
|
72 |
-
- Data fetching and state management
|
73 |
-
|
74 |
-
### Services
|
75 |
-
- API communication layer
|
76 |
-
- Request/response interceptors
|
77 |
-
- Error handling
|
78 |
-
- Authentication token management
|
79 |
-
|
80 |
-
### Store
|
81 |
-
- Redux store configuration
|
82 |
-
- State management for the entire application
|
83 |
-
- Actions and reducers for each feature
|
84 |
-
|
85 |
-
### Hooks
|
86 |
-
- Custom React hooks for reusable logic
|
87 |
-
- Custom authentication hook
|
88 |
-
- Data fetching hooks
|
89 |
-
|
90 |
-
### Styles
|
91 |
-
- CSS files organized by feature
|
92 |
-
- Global styles and variables
|
93 |
-
- Responsive design considerations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package.json
CHANGED
@@ -9,9 +9,9 @@
|
|
9 |
"install:all": "npm run install:frontend && npm run install:backend",
|
10 |
"install:all:win": "npm run install:frontend && cd backend && python -m pip install -r requirements.txt",
|
11 |
"dev:frontend": "cd frontend && npm run dev",
|
12 |
-
"dev:backend": "cd backend &&
|
13 |
-
"dev:all": "concurrently \"npm run dev:frontend\" \"npm run dev:backend\"",
|
14 |
-
"dev": "
|
15 |
"build": "cd frontend && npm run build",
|
16 |
"build:prod": "cd frontend && npm run build:prod",
|
17 |
"preview": "cd frontend && npm run preview",
|
@@ -21,7 +21,7 @@
|
|
21 |
"test:backend": "cd backend && pytest",
|
22 |
"start": "npm run dev:all",
|
23 |
"start:frontend": "npm run dev:frontend",
|
24 |
-
"start:backend": "
|
25 |
"setup": "npm run install:all && npm run build",
|
26 |
"setup:win": "npm run install:all:win && npm run build",
|
27 |
"clean": "cd frontend && npm run clean 2>/dev/null || true",
|
|
|
9 |
"install:all": "npm run install:frontend && npm run install:backend",
|
10 |
"install:all:win": "npm run install:frontend && cd backend && python -m pip install -r requirements.txt",
|
11 |
"dev:frontend": "cd frontend && npm run dev",
|
12 |
+
"dev:backend": "cd backend && python app.py",
|
13 |
+
"dev:all": "cd frontend && npx concurrently \"npm run dev:frontend\" \"npm run dev:backend\"",
|
14 |
+
"dev": "npm run dev:all",
|
15 |
"build": "cd frontend && npm run build",
|
16 |
"build:prod": "cd frontend && npm run build:prod",
|
17 |
"preview": "cd frontend && npm run preview",
|
|
|
21 |
"test:backend": "cd backend && pytest",
|
22 |
"start": "npm run dev:all",
|
23 |
"start:frontend": "npm run dev:frontend",
|
24 |
+
"start:backend": "cd backend && python app.py",
|
25 |
"setup": "npm run install:all && npm run build",
|
26 |
"setup:win": "npm run install:all:win && npm run build",
|
27 |
"clean": "cd frontend && npm run clean 2>/dev/null || true",
|
starty.py
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
"""
|
3 |
+
Lin - Community Manager Assistant for LinkedIn
|
4 |
+
Universal startup script for development servers
|
5 |
+
"""
|
6 |
+
import os
|
7 |
+
import sys
|
8 |
+
import subprocess
|
9 |
+
import platform
|
10 |
+
from pathlib import Path
|
11 |
+
|
12 |
+
def is_windows():
|
13 |
+
"""Check if the current OS is Windows"""
|
14 |
+
return platform.system().lower() == 'windows'
|
15 |
+
|
16 |
+
def run_command(command, cwd=None, shell=False):
|
17 |
+
"""Run a command and stream output"""
|
18 |
+
try:
|
19 |
+
# For Windows, we need to use shell=True for certain commands
|
20 |
+
use_shell = shell or is_windows()
|
21 |
+
|
22 |
+
process = subprocess.Popen(
|
23 |
+
command,
|
24 |
+
cwd=cwd,
|
25 |
+
shell=use_shell,
|
26 |
+
stdout=subprocess.PIPE,
|
27 |
+
stderr=subprocess.STDOUT,
|
28 |
+
text=True,
|
29 |
+
bufsize=1,
|
30 |
+
universal_newlines=True
|
31 |
+
)
|
32 |
+
|
33 |
+
# Stream output in real-time
|
34 |
+
for line in process.stdout:
|
35 |
+
print(line, end='')
|
36 |
+
|
37 |
+
process.wait()
|
38 |
+
return process.returncode == 0
|
39 |
+
except Exception as e:
|
40 |
+
print(f"Error running command: {e}")
|
41 |
+
return False
|
42 |
+
|
43 |
+
def start_frontend():
|
44 |
+
"""Start the React frontend development server"""
|
45 |
+
print("Starting frontend development server...")
|
46 |
+
if is_windows():
|
47 |
+
cmd = "npm run dev:frontend"
|
48 |
+
else:
|
49 |
+
cmd = ["npm", "run", "dev:frontend"]
|
50 |
+
return run_command(cmd, shell=True)
|
51 |
+
|
52 |
+
def start_backend():
|
53 |
+
"""Start the Flask backend server"""
|
54 |
+
print("Starting backend server...")
|
55 |
+
|
56 |
+
# Set environment variables and run the app
|
57 |
+
env = os.environ.copy()
|
58 |
+
# Add the project root to PYTHONPATH to ensure imports work correctly
|
59 |
+
env["PYTHONPATH"] = str(Path(__file__).parent)
|
60 |
+
|
61 |
+
try:
|
62 |
+
# Run the Flask app directly from the root directory
|
63 |
+
process = subprocess.Popen(
|
64 |
+
[sys.executable, "app.py"],
|
65 |
+
cwd=Path(__file__).parent,
|
66 |
+
env=env,
|
67 |
+
stdout=subprocess.PIPE,
|
68 |
+
stderr=subprocess.STDOUT,
|
69 |
+
text=True,
|
70 |
+
bufsize=1,
|
71 |
+
universal_newlines=True
|
72 |
+
)
|
73 |
+
|
74 |
+
# Stream output
|
75 |
+
for line in process.stdout:
|
76 |
+
print(line, end='')
|
77 |
+
|
78 |
+
process.wait()
|
79 |
+
return process.returncode == 0
|
80 |
+
except Exception as e:
|
81 |
+
print(f"Error starting backend: {e}")
|
82 |
+
return False
|
83 |
+
|
84 |
+
def start_all():
|
85 |
+
"""Start both frontend and backend using npm concurrently script"""
|
86 |
+
print("Starting both frontend and backend servers...")
|
87 |
+
# Use the frontend's concurrently script to run both servers
|
88 |
+
if is_windows():
|
89 |
+
cmd = "cd frontend && npx concurrently \"npm run dev:frontend\" \"npm run dev:backend\""
|
90 |
+
else:
|
91 |
+
cmd = "cd frontend && npx concurrently \"npm run dev:frontend\" \"npm run dev:backend\""
|
92 |
+
return run_command(cmd, shell=True)
|
93 |
+
|
94 |
+
def show_help():
|
95 |
+
"""Display usage information"""
|
96 |
+
help_text = """
|
97 |
+
Lin Development Launcher
|
98 |
+
|
99 |
+
Usage:
|
100 |
+
python starty.py [command]
|
101 |
+
|
102 |
+
Commands:
|
103 |
+
backend Start only the backend server (default)
|
104 |
+
frontend Start only the frontend development server
|
105 |
+
dev:all Start both frontend and backend servers
|
106 |
+
help Show this help message
|
107 |
+
|
108 |
+
Examples:
|
109 |
+
python starty.py # Start backend server
|
110 |
+
python starty.py backend # Start backend server
|
111 |
+
python starty.py frontend # Start frontend server
|
112 |
+
python starty.py dev:all # Start both servers
|
113 |
+
"""
|
114 |
+
print(help_text)
|
115 |
+
|
116 |
+
def main():
|
117 |
+
"""Main entry point"""
|
118 |
+
# Always ensure we're in the project root
|
119 |
+
project_root = Path(__file__).parent
|
120 |
+
os.chdir(project_root)
|
121 |
+
|
122 |
+
if len(sys.argv) < 2:
|
123 |
+
# Default behavior - start backend
|
124 |
+
start_backend()
|
125 |
+
return
|
126 |
+
|
127 |
+
command = sys.argv[1].lower()
|
128 |
+
|
129 |
+
if command in ['help', '--help', '-h']:
|
130 |
+
show_help()
|
131 |
+
elif command == 'frontend':
|
132 |
+
start_frontend()
|
133 |
+
elif command == 'backend':
|
134 |
+
start_backend()
|
135 |
+
elif command in ['dev:all', 'all', 'both']:
|
136 |
+
# Instead of calling npm run dev:all (which creates a loop),
|
137 |
+
# directly start both servers
|
138 |
+
start_all()
|
139 |
+
else:
|
140 |
+
print(f"Unknown command: {command}")
|
141 |
+
show_help()
|
142 |
+
sys.exit(1)
|
143 |
+
|
144 |
+
if __name__ == "__main__":
|
145 |
+
main()
|
test_imports.py
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
"""
|
3 |
+
Test script to verify backend imports work correctly
|
4 |
+
"""
|
5 |
+
import sys
|
6 |
+
import os
|
7 |
+
from pathlib import Path
|
8 |
+
|
9 |
+
# Add the project root to the Python path
|
10 |
+
project_root = Path(__file__).parent
|
11 |
+
sys.path.insert(0, str(project_root))
|
12 |
+
|
13 |
+
print("Testing backend imports...")
|
14 |
+
|
15 |
+
try:
|
16 |
+
# Test the import that was failing
|
17 |
+
from backend.services.content_service import ContentService
|
18 |
+
print("[SUCCESS] Successfully imported ContentService")
|
19 |
+
except ImportError as e:
|
20 |
+
print(f"[ERROR] Failed to import ContentService: {e}")
|
21 |
+
|
22 |
+
try:
|
23 |
+
# Test another service import
|
24 |
+
from backend.services.linkedin_service import LinkedInService
|
25 |
+
print("[SUCCESS] Successfully imported LinkedInService")
|
26 |
+
except ImportError as e:
|
27 |
+
print(f"[ERROR] Failed to import LinkedInService: {e}")
|
28 |
+
|
29 |
+
try:
|
30 |
+
# Test importing the app
|
31 |
+
from backend.app import create_app
|
32 |
+
print("[SUCCESS] Successfully imported create_app")
|
33 |
+
except ImportError as e:
|
34 |
+
print(f"[ERROR] Failed to import create_app: {e}")
|
35 |
+
|
36 |
+
print("Import test completed.")
|