Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
9.8 KiB
9.8 KiB
Phase 7 — User Accounts, Profiles, Media & Polish
Status: Complete ✅
All work targets the SERVER/ directory (live production copy).
Phase 7 has been expanded from profile polish into production CMS readiness: real delivery providers, scheduled publishing, media inventory, admin exports, and native systemd deployment. Docker is no longer the production deployment target.
7.1 — User Profiles & Usernames ✅
Goal: Every registered user gets a public profile page at /profile/@username.
Schema changes
User.username— unique, URL-safe slug (e.g.coaxys). Distinct fromUser.name(display name).User.bio— short biography (max 280 chars).User.avatarUrl— already added in Phase 6.5 (OAuth). Upload endpoint added here.
Backend routes
GET /api/profile/:username— public profile (name, bio, avatar, role, joined date, article count)PUT /api/auth/profile— update own profile (name, bio, username, avatarUrl)POST /api/auth/avatar— upload profile picture (JPEG/PNG → optional WebP conversion)
Frontend
- New file:
teknav-profile.jsx—UserProfilePagecomponent- Route:
/profile/@username(e.g./profile/@coaxys) - Theme: warm terracotta / burnt orange / deep sand — NOT teal
- Shows avatar, display name, @username, bio, role badge, join date, article list (if writer/editor)
- Route:
teknav-app.jsx— route dispatch updatedteknav-auth.jsx— profile settings section added to login page flow (accessible after login)
7.2 — Security & Auth Flows ✅
Forgot password
POST /api/auth/forgot-password— generates a reset token (Redis, 1h TTL) and sends the reset email through SMTP when configuredPOST /api/auth/reset-password— validates token + hashes new password- Frontend: "فراموشی رمز عبور" button on login page → modal flow
OTP (Phone)
POST /api/auth/otp/send— generates and sends a 6-digit OTP through Kavenegar whenSMS_PROVIDER=kavenegarandSMS_API_KEYare setPOST /api/auth/otp/verify— verifies OTP, stores the phone number, and marksphoneVerifiedAt- If SMS is not configured, the API returns a real
503state instead of pretending delivery happened
Email verification
POST /api/auth/email/verify/request— creates a one-hour Redis token and sends a verification link through SMTPPOST /api/auth/email/verify/confirm— validates the token for the current session and setsemailVerifiedAt- Profile settings expose email/phone verification controls without mock success states
7.3 — Media: Images in Articles ✅
Backend
POST /api/admin/uploadsalready exists (Phase 5). Extended with:?webp=1query param → server-side WebP conversion usingsharp(installed as optional dep)sharpis optional: if not installed, uploads proceed without conversion (no crash)
Frontend — Article Editor (HTML mode)
- HTML editor added to
ArticleEditorin admin panel (for writer/editor/admin roles) - Toolbar: Bold, Italic, Heading, Link, Unordered List, Ordered List, Blockquote, Code, HR
- Image insert: inline upload → returns
/uploads/yyyy/mm/uuid.extURL inserted into HTML - WebP conversion toggle in upload panel (off by default)
- Existing 3D diagram panel preserved alongside HTML editor (two tabs: "محتوا" / "نمودار")
MediaAssetrecords are now created for admin uploads and profile avatars, including filename, URL, MIME type, size, dimensions, uploader, and created dateGET /api/admin/mediapowers a real admin/editor media libraryDELETE /api/admin/media/:idremoves unused media and blocks deletion while referenced by content or avatars
7.4 — Remove All Mock/Placeholder Data ✅
Files cleaned:
teknav-home.jsx— StatsBar: "نویسنده فعال: ۸" → 3 (matches real seed authors)teknav-admin.jsxwriterStats— hardcoded 3/1/1 articles → computed from real API dataeditorStats—Math.min(published, 8)→ realpublishedcount- Dashboard "آخرین فعالیتها" — now loaded only from API; no TeknavStore.getActivity() fallback faked data
ArticlesManagement— TeknavStore fallback removed; shows empty state if API unavailable
teknav-data.js—activityLogkept for legacy reference only (not shown in UI)
7.5 — UI Polish ✅
Footer
- Copyright year:
۱۴۰۳→۱۴۰۵
Mobile responsiveness
- Header: hamburger menu already works; improved padding/font sizes
- Article cards: single column on < 480px
- Admin panel: sidebar collapses to bottom nav on mobile
- Login/signup form: better vertical spacing on small screens
- Profile page: single-column stack on mobile
Profile page design language
- Warm terracotta (
#C46A4D) / burnt orange (#A8512E) accents - Deep sand card backgrounds (
#F4EFE6) - Unique green (
#2F8F6B) for highlights (same as diagram accent) - Avatar with warm circular border
- No teal in profile UI
7.6 — Email + OTP Infrastructure ✅
Backend delivery
backend/src/lib/email.tssends through SMTP whenSMTP_HOSTis configured; otherwise it logs operator-visible output for non-production usebackend/src/lib/otp.tsstores Redis OTPs and sends real SMS through Kavenegar- Delivery failures are surfaced to the frontend and never shown as fake success
Env vars (add to /etc/teknav/backend.env)
# Email
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
SMTP_FROM=no-reply@teknav.ir
# SMS / OTP
SMS_PROVIDER=kavenegar
SMS_API_KEY=
SMS_SENDER=
7.8 — Scheduling, Exports & Operations ✅
Article scheduling
Article.scheduledAtand statusزمانبندیشدهare supported in the editorPOST /api/admin/articles/:id/schedulelets editor/admin roles schedule publicationbackend/scripts/publish-due.mjspublishes due articles and clears public cache keysdeploy/systemd/teknav-publish-due.timerruns the publisher every 5 minutes
Reporting
GET /api/admin/dashboardincludes real totals for users, authors, categories, tags, media, top articles, status counts, DB views, and Redis-buffered viewsGET /api/admin/activity/export.csvexports activity logs for admin users
Native deployment
- systemd units live in
deploy/systemd/ - log rotation lives in
deploy/logrotate/teknav - database backups run through
scripts/systemd-backup.shandteknav-backup.timer DEPLOY.mdis now the canonical non-Docker production runbook forwww.teknav.ir
Staff credentials
ACCOUNTS.mdcontains operator-facing initial credentials and is ignored by git- nginx blocks
/ACCOUNTS.md backend/prisma/credentials.jsonseeds the login records- Three writer-admin accounts were added for آرسام صباغ, رادمان قلیچی, and سیداحمدرضا محجوب
- Every seeded user now receives a username; login accepts email or
@username - Signup collects display name, username, and password; profile settings allow users of any role to edit display name, username, bio, verification data, and password
7.7 — WebP Image Optimization ✅
sharpinstalled as optional dependency inbackend/package.json- Upload route (
POST /api/admin/uploads) gains?webp=1query param - If
sharpis available andwebp=1: converts JPEG/PNG → WebP (quality 82), saves as.webp - Admin upload panel shows "تبدیل به WebP" checkbox (off by default)
- Profile avatar upload automatically converts to WebP if sharp is available
Phase 7 Checklist
Backend
User.username+User.bioin schemaGET /api/profile/:usernamePUT /api/auth/profilePOST /api/auth/avatarPOST /api/auth/forgot-passwordPOST /api/auth/reset-passwordPOST /api/auth/otp/sendPOST /api/auth/otp/verifyPOST /api/auth/email/verify/requestPOST /api/auth/email/verify/confirm- WebP upload option (
?webp=1) MediaAssetmodel + media library APIs- Article scheduling API + due publisher script
- Activity CSV export
backend/src/lib/email.tsSMTP senderbackend/src/lib/otp.ts.env.prod.exampleupdated with SMTP + SMS vars- Writer-admin seed accounts added to
backend/prisma/credentials.json - Login by email or
@username - Profile password update API
Frontend
teknav-profile.jsx— public profile page/profile/@usernameroute inteknav-app.jsx- Forgot password button + modal in
LoginPage - Profile picture upload in settings
- HTML editor in
ArticleEditor - Image insertion in articles
- WebP toggle in upload panels
- Media library panel with real API data only
- Scheduled publish controls in article editor
- Activity CSV export link
- Email/phone verification controls in profile settings
- Username field on signup
- Password editing in profile settings
- Footer year → 1405
- StatsBar "نویسنده فعال" → 3
- Mock data removed from admin panel
- Mobile responsiveness improvements
Docs
MEMORY.mdupdatedARCH.mdupdatedSECURITY.mdupdatedDEPLOY.mdupdated for native systemd deployment and SMTP/SMS varsPHASE7.mdwrittenACCOUNTS.mdadded, gitignored, and nginx-blocked
Dependencies Added
| Package | Location | Purpose |
|---|---|---|
sharp |
backend (optional) |
WebP image conversion |
nodemailer |
backend |
SMTP email delivery |
Install on server: cd backend && npm install sharp (or it's included if added to package.json)
Notes
- Phone OTP requires Kavenegar credentials on the Linux server.
- Forgot-password and email verification require SMTP credentials on the Linux server.
sharpis optional: if not installed, uploads work normally as JPEG/PNG. WebP toggle in the UI gracefully falls back.