Welcome to the MyRobocon Portal! This document serves as a comprehensive guide to understanding, running, managing, and extending the portal.
- Overview
- Tech Stack
- Project Structure
- Getting Started
- Core Concepts
- Portal Features
- API Endpoints
- Data Recovery
- Self-Hosting
- Customization and Extension * Adding New Pages * Modifying Components * Extending Data Models
- Troubleshooting
The MyRobocon Portal is a web application designed to manage participants, teams, resources, announcements, and team progress for a Robocon-style competition. It provides separate interfaces for administrators and participants.
Key Features:
- User authentication with distinct roles (admin, participant).
- Management dashboards for teams, users, resources, and announcements.
- Participant-specific views for team information, resources, progress submissions, and notifications.
- Admin interface for reviewing team progress, awarding points, providing feedback, sending manual notifications, and managing bulk email campaigns.
- Site branding, theme customization, configurable team progress point quotas, and SMTP email settings.
- Admin-managed API keys for external integrations.
- Encrypted file-based data storage for enhanced security and easy portability.
- Extensible with Next.js API routes for features like announcements and external system integration (e.g., team import, dashboard data).
- In-app notification system for users.
- The portal can act as a centralized SSO (Single Sign-On) provider for other applications, using OAuth 2.0.
- Advanced email automation with templates, triggers, and scheduling.
- Passkey support for secure, passwordless authentication.
- Framework: Next.js (App Router)
- UI Library: React
- Component Library: ShadCN UI
- Styling: Tailwind CSS
- Authentication:
oidc-provider(for SSO),@simplewebauthn/server(for passkeys) - Email: Nodemailer
- Language: TypeScript
- Data Storage: Encrypted local JSON files (managed via server actions)
.
├── .data/ # Persisted application data (JSON files) - Created at runtime
├── .vscode/ # VS Code settings
├── public/ # Static assets (e.g., favicon)
├── scripts/
│ ├── generate-secret.js # Helper script for creating the encryption key
│ └── decrypt-value.js # Helper script for decrypting a value
├── src/
│ ├── actions/ # Server Actions for data manipulation
│ ├── app/ # Next.js App Router: pages, layouts, API routes
│ │ ├── (admin)/ # Admin-specific routes and layout
│ │ │ └── admin/
│ │ │ ├── announcements/
│ │ │ ├── email/ # Admin page for sending email campaigns
│ │ │ ├── notifications/ # Admin page for sending manual notifications
│ │ │ ├── progress-review/
│ │ │ ├── resources/
│ │ │ ├── settings/
│ │ │ ├── teams/
│ │ │ └── users/
│ │ ├── (participant)/ # Participant-specific routes and layout
│ │ │ ├── my-team/
│ │ │ └── progress/
│ │ ├── api/ # API routes
│ │ │ ├── announcements/
│ │ │ ├── passkeys/ # Endpoints for WebAuthn/Passkey ceremonies
│ │ │ └── v1/
│ │ │ ├── dashboard/ # Endpoints for external dashboards
│ │ │ │ ├── progress-submissions/
│ │ │ │ ├── stats/
│ │ │ │ └── teams/
│ │ │ └── import/
│ │ │ └── team-and-users/ # API for external team/user import
│ │ ├── globals.css # Global styles and Tailwind directives
│ │ ├── layout.tsx # Root layout
│ │ ├── login/ # Login page
│ │ └── page.tsx # Root page (handles redirection)
│ ├── components/ # Reusable React components
│ │ └── ui/ # ShadCN UI components
│ ├── contexts/ # React Context providers (Auth, Settings)
│ ├── hooks/ # Custom React Hooks
│ ├── lib/ # Utility functions, type definitions, file utils
│ └── services/ # Business logic services (e.g., email)
├── components.json # ShadCN UI configuration
├── next.config.ts # Next.js configuration
├── package.json # Project dependencies and scripts
├── tailwind.config.ts # Tailwind CSS configuration
├── tsconfig.json # TypeScript configuration
└── README.md # This file
└── README.md # This file
- Node.js (v18 or later recommended)
- npm or yarn
- Clone the repository:
git clonerepository_url>gt; cd project_directory>gt; - Install dependencies:
npm install # or # yarn install
The application uses strong encryption to protect sensitive data (passwords, API keys, etc.) stored in the .data directory. To run the application, you must generate a secret encryption key.
-
Generate the Key: Run the following command in your terminal:
npm run setup:encrypt
This will generate a secure, random key and display a line like this:
ENCRYPTION_SECRET=a1b2c3d4e5f6... -
Create
.env.localfile: In the root of your project directory, create a new file named.env.local. -
Add the Key: Copy the entire
ENCRYPTION_SECRET=...line from the terminal and paste it into your new.env.localfile.
IMPORTANT:
- The
ENCRYPTION_SECRETis vital. If you lose it, all encrypted data will become permanently unreadable. Back it up securely. - Do NOT commit your
.env.localfile to version control.
For features like Passkeys and SSO to work correctly, the application needs to know its own public URL. This is also configured in your .env.local file.
- Open your
.env.localfile (the same one where you added the encryption secret). - Add the following line, replacing the URL with the one for your development or production environment:
For example, in a Google Cloud Workstation, this would be your workstation's URL. For local development on your own machine, you can use
OIDC_ISSUER=https://your-public-url.comhttp://localhost:9002. If this variable is not set, it will default tohttp://localhost:9002.
To use the email campaign feature, you must configure your SMTP service credentials. This is done directly within the application's admin interface for security and ease of management.
- Run the application (
npm run dev) and log in as an administrator. - Navigate to Site Settings from the sidebar.
- Find the SMTP Email Settings card.
- Enter your SMTP server details:
- SMTP Host: The hostname of your SMTP server (e.g.,
smtp.office365.com). - SMTP Port: The port number (e.g.,
587for TLS, or465for SSL). - SMTP Username: Your email address/username for the SMTP service.
- SMTP Password: Your password for the SMTP service. Crucially, for services like Outlook or Gmail, you must generate a special "App Password" from your account's security settings and use that here. Using your main account password may not work.
- Sender Name: The name that will appear in the "From" field of emails (e.g., "MyRobocon Portal Admin").
- Sender Email: The email address that will appear in the "From" field.
- SMTP Host: The hostname of your SMTP server (e.g.,
- Click "Save All Settings" at the bottom of the page. The credentials will be saved securely and encrypted in the
.data/settings.jsonfile.
To start the development server:
npm run devThis will typically start the app on http://localhost:9002.
To create an optimized production build:
npm run buildThis command compiles your Next.js application and outputs the build artifacts to the .next directory.
After building, you can start the production server:
npm startBy default, this script is configured to attempt running on port 80 (next start -p 80). See the Self-Hosting section for important considerations about running on port 80/443.
The portal uses a simple file-based data storage system. All application data (users, teams, announcements, etc.) is stored as JSON files within the .data directory at the root of the project. This directory is created automatically if it doesn't exist.
Sensitive data within these files (passwords, API keys, etc.) is encrypted using AES-256-GCM.
Key Data Files:
.data/users.json: Stores user accounts and credentials..data/teams.json: Stores team information..data/resources.json: Stores resources for teams..data/announcements.json: Stores site announcements..data/settings.json: Stores site configuration like title, logo, theme, progress point quotas, API tokens, and SMTP credentials..data/progress_submissions.json: Stores team progress updates..data/notifications.json: Stores user notifications..data/email_templates.json: Stores reusable email templates..data/scheduled_emails.json: Stores emails that are scheduled to be sent.
Note: This file-based storage is suitable for single-instance deployments or development. For multi-instance or serverless deployments, consider migrating to a database.
Data fetching and mutations are primarily handled using Next.js Server Actions. These are functions defined in src/actions/*.ts. They execute on the server and can be called directly from client components, simplifying data flow. They interact with the encrypted JSON data files via src/lib/file-utils.ts.
User authentication is managed through the users.json file.
- Credentials Check: The
AuthContext(src/contexts/AuthContext.tsx) handles login logic. - Session Management: Basic session management is handled by storing user information in
localStorage. - Roles: Users can have "admin" or "participant" roles.
- Protected Routes:
src/components/ProtectedRoute.tsxensures only authenticated users with the correct roles can access specific routes. - Self-Service Password Change: Users can change their own passwords via the user menu in the site header.
- Passkey Support (Passwordless Login): The portal supports WebAuthn for highly secure, passwordless authentication. Any user can register multiple passkeys (e.g., Face ID, Windows Hello, fingerprint, YubiKey) to their account via the "Security & Passkeys" option in the user menu. Once a passkey is registered, they can use it for a fast and secure login experience. This is especially useful for teams, as multiple members can register their own device's passkey to a shared team account, eliminating the need to share passwords.rds.
The portal uses the Next.js App Router.
- Admin Area: Routes under
/adminare protected and use the layout defined insrc/app/(admin)/layout.tsx. - Participant Area: Routes under
/my-teamand/progressare for participants and use the layout fromsrc/app/(participant)/layout.tsx. - Login Page:
src/app/login/page.tsxis the entry point for authentication. - Root Page:
src/app/page.tsxhandles redirection based on authentication status.
- ShadCN UI: Components are in
src/components/ui/. - Tailwind CSS: Used for all styling.
The portal supports multiple themes, managed in "Site Settings". The ThemeProvider from next-themes is used for light/dark mode toggling in the "Normal" theme.
User-specific notifications are generated for resource updates, progress status changes, or sent manually by admins. They appear in the site header.
- Overview of key metrics: total teams, total resources.
- Displays the latest active announcement.
- Quick links to management sections.
- Full CRUD operations for teams.
- CSV Import/Export.
- Bulk actions for deleting teams or setting their banner image.
- Full CRUD for users.
- Manual password setting for any user.
- CSV Import/Export.
- Bulk actions for deleting users or setting passwords.
- Manage resources with content, links, and team assignments.
- Manage site-wide announcements, including their content, type, and display location.
- Review, comment on, and assign points to team progress submissions.
- Approve or reject submissions, which affects team point totals.
- Manage submitted images (download or clear data).
- Compose Email: Paste raw HTML code for your email design and enter a subject line.
- Personalization Placeholders: Use
{{name}},{{teamName}},{{schoolName}}in the subject and HTML body. - Preview: Render a preview of the HTML before sending.
- Targeting: Send emails to All Users, All Participants, All Admins, or a specific Team.
- Sending: Uses the external SMTP service configured in Site Settings.
- Email Templates: Create and manage reusable email templates for campaigns or automated notifications.
- Automated Email Triggers: Emails are automatically sent when new users are created or when progress submissions are approved/rejected.
- Email Scheduling: Schedule email campaigns to be sent at a future date and time. This requires an external service (like a cron job) to periodically call a specific API endpoint to trigger the send process.
- Compose and send manual in-app notifications to users or teams.
- Branding: Customize site title, logo URL, login page hint, and footer text.
- SMTP Email Settings: Configure the external email service used by the Email Campaign feature.
- Site Theme: Select the active theme for the portal.
- Progress Quotas: Set the "Max Progress Points Per Team".
- Site Access Modes: Enable/disable Demo Mode (shows default credentials on login) or Maintenance Mode (blocks participant logins).
- API Token Management: Create, view (masked), and delete API tokens used for external integrations.
- OAuth Application Management (SSO Provider): Register external applications that can use this portal for login.
- Displays team information, assigned resources, and active announcements.
- Participants can mark resources as read/unread.
- Includes an "Account Security" card to guide users in setting up Passkeys for passwordless login.
- Submit progress updates with an image and description.
- View submission history, points awarded, and admin feedback.
- View a progress bar showing earned points against the team's quota.
- A bell icon in the site header indicates new notifications.
All API endpoints are authenticated using Bearer tokens. Valid tokens are managed by administrators on the "Site Settings" page.
- Method:
GET,POST - Auth: Bearer token.
GET: Returns a list of all active announcements.POST: Creates a new announcement.
- Method:
POST - Path:
/api/v1/import/team-and-users - Auth: Bearer token.
- Purpose: Allows an external system to programmatically create a new team and its users.
- Request Body (JSON): See the route file
src/app/api/v1/import/team-and-users/route.tsfor the exact payload structure. It acceptsteamData,teamLeadUserData, andstudentMemberData.
These endpoints are designed to provide data for external dashboards.
- Returns: A JSON object with key statistics (total teams, users, submissions by status, etc.).
- Returns: A JSON array of all teams (WiFi password is omitted).
- Returns: A JSON array of all progress submissions.
Create new route handlers under src/app/api/. Implement authentication by loading API keys from settings and validating the Bearer token.
If you ever need to manually decrypt a value from one of the .data/*.json files (e.g., a user's password for troubleshooting), you can use the built-in decryption script.
Prerequisites:
- You must have command-line access to the server where the portal is running.
- The
ENCRYPTION_SECRETmust be correctly set in the.env.localfile.
Usage:
-
Find the encrypted value in the JSON file. It will be a long string with
::separators. -
Run the following command, replacing
with the value you copied:ng> npm run decrypt -- "ng>" "ing>"" tabindex="0" role="button"> Note: It's important to wrap the encrypted string in quotes to prevent the shell from misinterpreting special characters.
-
The script will print the decrypted, plaintext value to your console.
- Build the app:
npm run build - Run the app:
npm start - Permissions: Ensure the Node.js process has write permissions to the project's root directory to create and write to the
.datafolder. - Reverse Proxy (Recommended): Use Nginx or Apache as a reverse proxy to handle traffic on ports 80/443 and forward it to the Next.js app running on an unprivileged port (e.g., 3000).
- Process Manager: Use a process manager like PM2 to keep the application running.
- Add new route segments under
src/app/(admin)/admin/orsrc/app/(participant)/. - Update navigation links in
src/app/(admin)/layout.tsxorsrc/components/SiteHeader.tsx.
- ShadCN UI components are in
src/components/ui/. - Custom application components are in
src/components/.
- Update the TypeScript interfaces in
src/lib/types.ts. - Update default data structures in
src/actions/*Actions.ts. - Update any UI components, forms, and server actions that interact with the modified data model.
- If modifying data files directly, ensure your application logic can handle older entries that might not have the new fields.
- Application Fails to Start (ENCRYPTION_SECRET error): This is the most common error after setup. Ensure you have run
npm run setup:encryptand have correctly added theENCRYPTION_SECRET=...line to a.env.localfile in the project's root directory. - Data Not Saving: Check write permissions for the
.datafolder. - Emails Not Sending:
- Double-check your SMTP credentials in Site Settings.
- Ensure your SMTP provider (e.g., Outlook, Gmail) allows SMTP access. You may need to enable it.
- Verify you are using an "App Password" if your provider requires it.
- Check the terminal where your Next.js app is running for any error messages from Nodemailer.
- Passkey/SSO Errors: Ensure the
OIDC_ISSUERenvironment variable is set correctly in your.env.localfile to match your public URL. - Incorrect CSV Import: Ensure your CSV file adheres strictly to the required headers and format.
- API Errors (401 Unauthorized): Ensure the
Authorization: Bearerheader is correctly sent. Verify the token exists and is correct in "Site Settings" > "API Token Management".t".en> - Large Data Files: For high usage,
progress_submissions.json(with image data) can become large. Consider an external file storage solution or using the "Clear Image Data" feature in the progress review modal.