Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RuangJujur

A mental health web application for Indonesian Gen Z university students. Part of the Vesya-Who project. RuangJujur provides a safe, anonymous space for students to express their feelings through AI-powered chat, mood tracking, and guided self-reflection.

Freemium model: Anonymous chat on the landing page serves as the entry point. Users are encouraged to register for full features including mood tracking, permanent chat history, and saved AI suggestions.


Tech Stack

Layer Technology
Backend Framework Laravel 13.x
Backend Language PHP 8.3
Frontend Library React 18
SPA Bridge Inertia.js 2
Styling Tailwind CSS 4
Build Tool Vite 8
AI / LLM API Openclaw API (Llama 3.1 8B Instant)
Authentication Laravel Breeze 2.4 + Sanctum 4.0
Database (default) SQLite
Database (optional) MySQL, PostgreSQL, Redis
Testing PHPUnit 12
PHP Package Manager Composer
JS Package Manager npm
Linter Laravel Pint
Queue Driver database

Project Structure

RuangJujur/
├── app/
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── Auth/                       # Breeze authentication controllers
│   │   │   ├── AnonymousChatController.php # Anonymous chat with AI
│   │   │   ├── Controller.php              # Base controller
│   │   │   ├── MoodCanvasController.php    # Mood tracking & visualization
│   │   │   └── ProfileController.php       # User profile CRUD
│   │   ├── Middleware/
│   │   │   └── HandleInertiaRequests.php   # Inertia.js middleware
│   │   └── Requests/
│   │       ├── Auth/
│   │       │   └── LoginRequest.php
│   │       └── ProfileUpdateRequest.php
│   ├── Models/
│   │   ├── AnonymousSession.php            # Anonymous chat session (UUID-based)
│   │   ├── ChatMessage.php                 # Chat messages (user or AI)
│   │   ├── ChatSession.php                 # Registered user chat sessions
│   │   ├── SavedSuggestion.php             # Bookmarked AI suggestions
│   │   └── User.php                        # User model
│   ├── Providers/
│   │   └── AppServiceProvider.php
│   └── Services/
│       ├── AnonymousNameGenerator.php      # Nature-themed pseudonym generator
│       └── OpenClawApiService.php          # AI API integration + crisis detection
│
├── bootstrap/
│   ├── app.php
│   ├── cache/
│   └── providers.php
│
├── config/
│   ├── app.php
│   ├── auth.php
│   ├── cache.php
│   ├── database.php
│   ├── filesystems.php
│   ├── logging.php
│   ├── mail.php
│   ├── queue.php
│   ├── services.php                        # Openclaw API configuration
│   └── session.php
│
├── database/
│   ├── factories/
│   │   └── UserFactory.php
│   ├── migrations/
│   │   ├── 0001_01_01_000000_create_users_table.php
│   │   ├── 0001_01_01_000001_create_cache_table.php
│   │   ├── 0001_01_01_000002_create_jobs_table.php
│   │   ├── 2026_07_06_035549_create_chat_sessions_table.php
│   │   ├── 2026_07_06_035550_create_chat_messages_table.php
│   │   ├── 2026_07_06_035551_create_saved_suggestions_table.php
│   │   └── 2026_07_06_042151_create_anonymous_sessions_table.php
│   └── seeders/
│       └── DatabaseSeeder.php
│
├── public/
│   ├── .htaccess
│   ├── favicon.ico
│   ├── index.php
│   └── robots.txt
│
├── resources/
│   ├── css/
│   │   └── app.css                         # Tailwind CSS entry point
│   ├── js/
│   │   ├── app.jsx                         # Inertia React entry point
│   │   ├── bootstrap.js
│   │   ├── Components/                     # Reusable UI components (12 files)
│   │   │   ├── ApplicationLogo.jsx
│   │   │   ├── Checkbox.jsx
│   │   │   ├── DangerButton.jsx
│   │   │   ├── Dropdown.jsx
│   │   │   ├── InputError.jsx
│   │   │   ├── InputLabel.jsx
│   │   │   ├── Modal.jsx
│   │   │   ├── NavLink.jsx
│   │   │   ├── PrimaryButton.jsx
│   │   │   ├── ResponsiveNavLink.jsx
│   │   │   ├── SecondaryButton.jsx
│   │   │   └── TextInput.jsx
│   │   ├── Layouts/                        # Page layout wrappers
│   │   │   ├── AppLayout.jsx
│   │   │   ├── AuthenticatedLayout.jsx
│   │   │   ├── GuestLayout.jsx
│   │   │   ├── PublicLayout.jsx            # Public-facing layout (navbar + footer)
│   │   │   └── WorkspaceLayout.jsx         # Authenticated user workspace (sidebar)
│   │   └── Pages/
│   │       ├── AIAssistant/Index.jsx       # AI assistant (placeholder)
│   │       ├── AnonymousChat/Index.jsx     # Anonymous chat UI
│   │       ├── Archive/Index.jsx           # Chat archive (placeholder)
│   │       ├── Auth/                       # Authentication pages
│   │       │   ├── ConfirmPassword.jsx
│   │       │   ├── ForgotPassword.jsx
│   │       │   ├── Login.jsx
│   │       │   ├── Register.jsx
│   │       │   ├── ResetPassword.jsx
│   │       │   └── VerifyEmail.jsx
│   │       ├── Dashboard/Index.jsx         # User dashboard (placeholder)
│   │       ├── Landing/Index.jsx           # Landing page (hero + features + testimonials)
│   │       ├── MoodCanvas/Index.jsx        # Mood tracking (calendar + weekly graph)
│   │       └── Profile/
│   │           ├── Edit.jsx
│   │           └── Partials/
│   │               ├── DeleteUserForm.jsx
│   │               ├── UpdatePasswordForm.jsx
│   │               └── UpdateProfileInformationForm.jsx
│   └── views/
│       └── app.blade.php                   # Root Blade template (Inertia mount point)
│
├── routes/
│   ├── auth.php                            # Authentication routes (Breeze)
│   ├── console.php                         # Artisan CLI routes
│   └── web.php                             # Application routes
│
├── storage/                                # Laravel storage (logs, cache, sessions)
├── tests/
│   ├── TestCase.php
│   ├── Feature/
│   │   ├── Auth/
│   │   ├── ExampleTest.php
│   │   └── ProfileTest.php
│   └── Unit/
│       └── ExampleTest.php
│
├── composer.json
├── package.json
├── vite.config.js
├── tailwind.config.js
├── phpunit.xml
├── jsconfig.json
└── .env.example

Database Schema

users

Column Type Description
id bigint (PK) Auto-increment
name string User display name
email string Unique email
email_verified_at timestamp Email verification time
password string Hashed password
remember_token string Remember me token
created_at timestamp
updated_at timestamp

anonymous_sessions

Column Type Description
id uuid (PK) Browser session token (UUID)
pseudonym string Nature-themed alias (e.g. "Bulan Tenang #456")
messages_count integer Messages sent (soft-limit 15)
status enum active / crisis
metadata json Stores chat_history array
created_at timestamp
updated_at timestamp

chat_sessions

Column Type Description
id bigint (PK) Auto-increment
user_id bigint (FK) References users (cascade)
title string Chat session title
is_archived boolean Archive status
created_at timestamp
updated_at timestamp

chat_messages

Column Type Description
id bigint (PK) Auto-increment
chat_session_id bigint (FK) References chat_sessions (cascade)
is_user boolean true = user, false = AI
message text Message content
created_at timestamp
updated_at timestamp

saved_suggestions

Column Type Description
id bigint (PK) Auto-increment
user_id bigint (FK) References users (cascade)
title string Suggestion title
category string Suggestion category
ai_response text Saved AI response
created_at timestamp
updated_at timestamp

Routes

Method Path Controller Middleware Description
GET / Landing/Index guest Landing page
POST /anonymous-chat/send AnonymousChatController::sendMessage guest Send anonymous chat message
GET /login AuthenticatedSessionController guest Login page
POST /login AuthenticatedSessionController guest Process login
GET /register RegisteredUserController guest Registration page
POST /register RegisteredUserController guest Process registration
GET /forgot-password PasswordResetLinkController guest Forgot password
POST /forgot-password PasswordResetLinkController guest Send reset link
GET /reset-password/{tkn} NewPasswordController guest Reset password form
POST /reset-password NewPasswordController guest Process password reset
GET /verify-email EmailVerificationPromptController auth Email verification prompt
GET /verify-email/{id}/{h} VerifyEmailController auth, signed Process email verification
POST /email/verif-notif EmailVerificationNotificationCtrl auth, throttle Resend verification email
GET /confirm-password ConfirmablePasswordController auth Confirm password
POST /confirm-password ConfirmablePasswordController auth Process confirmation
PUT /password PasswordController auth Update password
POST /logout AuthenticatedSessionController auth Logout
GET /dashboard Dashboard/Index auth, verified User dashboard
GET /mood-canvas MoodCanvasController::index auth, verified Mood Canvas (calendar + graph)
POST /mood-canvas MoodCanvasController::store auth, verified Save daily mood log
GET /archive Archive/Index auth, verified Chat session archive
GET /ai-assistant AIAssistant/Index auth, verified AI Assistant

Features

Anonymous Chat

  • AI-powered chat using Llama 3.1 via Openclaw API
  • Nature-themed pseudonym generator (e.g. "Ombak Lembut #742")
  • Crisis detection for Indonesian self-harm keywords with emergency hotline referral (Kemenkes RI 119 ext 8)
  • Soft limit of 15 messages per session to encourage registration
  • Chat history stored in session metadata (no link to user identity)

Mood Canvas

  • Daily mood logging with 5 mood types: senang, tenang, biasa, sedih, cemas
  • Monthly calendar view with color-coded mood entries
  • Weekly trend graph (SVG polyline visualization)
  • Duplicate prevention (one log per day)
  • Optional journal notes (max 300 characters)

Landing Page

  • Hero section with social proof
  • Feature showcase (bento grid layout)
  • Anonymous testimonials from students

Authentication

  • Full Breeze authentication (register, login, password reset, email verification)
  • Email verification required for authenticated features

Security Features

  1. Crisis Detection (Input Guardrail) — 8 Indonesian self-harm keywords are checked before sending messages to AI. If detected, the session is flagged as crisis, an emergency response with hotline number is displayed, and the message is NOT sent to AI.

  2. Anonymity — Anonymous chat uses UUID tokens stored in browser sessions. No connection to user identity. Display names are random nature-themed pseudonyms.

  3. Soft Limit — 15 messages per anonymous session. When reached, users are encouraged to register for permanent chat history.

  4. System Prompt Guardrails — AI is instructed to:

    • Use casual Indonesian language only
    • Never provide medical diagnoses
    • Never prescribe medication
    • Limit responses to 2-3 sentences
    • Use Reflective Listening technique
  5. Email Verification — Required for all authenticated features (verified middleware).


Getting Started

Prerequisites

  • PHP 8.3+
  • Composer
  • Node.js & npm
  • SQLite (or MySQL/PostgreSQL)

Installation

  1. Clone the repository:

    git clone <repository-url>
    cd RuangJujur
  2. Install PHP dependencies:

    composer install
  3. Install JavaScript dependencies:

    npm install
  4. Copy the environment file:

    cp .env.example .env
  5. Generate the application key:

    php artisan key:generate
  6. Configure your .env file:

    DB_CONNECTION=sqlite
    
    OPENCLAW_API_KEY=your_openclaw_api_key
    OPENCLAW_MODEL=your_model_name
    
  7. Run database migrations:

    php artisan migrate
  8. Seed the database (optional — creates a test user):

    php artisan db:seed
  9. Build frontend assets:

    npm run dev
  10. Start the development server:

    php artisan serve

Running Tests

php artisan test

Code Linting

./vendor/bin/pint

Known Issues

  1. Placeholder pages — Three pages are still minimal/empty:

    • AIAssistant/Index.jsx
    • Archive/Index.jsx
    • Dashboard/Index.jsx
  2. Registered user chat not implemented — Models, migrations, and route placeholders exist, but no controller or page connects registered users to the AI assistant.

  3. Static calendar navigation — Prev/next month buttons in MoodCanvas/Index.jsx have no functional handlers.


License

This project is part of the Vesya-Who initiative.

About

sebuah web site untuk rehabilitas dan teman chat

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages