Getting Started
Local setup for the Meetyy API, and a reference for every account and record the seeders create β so you can log in as a mentor with a full calendar, or a mentee mid-way through a community, without clicking anything into existence first.
- Stack: PHP 8.3 Β· Laravel 13 Β· MySQL Β· Redis (Horizon)
- Auth: Sanctum bearer tokens β see Authentication
- Endpoint reference:
/docs/section/api
Local only. Every credential on this page is a development fixture committed to the repo. The seeders are not safe to run against a shared or production database β see Re-running seeders.
Requirements
| Requirement | Notes |
|---|---|
| PHP | 8.3 |
| MySQL | Required. CountryStateSeeder is MySQL-specific and fails on SQLite |
| Composer | β |
| Node | For npm run build / npm run dev |
| Redis | For queues via Horizon β slot generation runs on a queue |
Setup
composer install
cp .env.example .env
php artisan key:generate
.env.exampleis stock Laravel and will not work as-is. It shipsDB_CONNECTION=sqlitewith everyDB_*line commented out. BecauseCountryStateSeederuses MySQL-only syntax (DB::unprepared,SET FOREIGN_KEY_CHECKS, backtick-quoted staging tables), a fresh clone that follows.env.examplecannot seed. Set MySQL explicitly before continuing.
Edit .env:
APP_NAME=Meetyy
APP_URL=http://meetyy-api.test
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=meetyy_api
DB_USERNAME=root
DB_PASSWORD=
Then create the database and seed it:
php artisan migrate:fresh --seed
composer setuprunsmigratewithout--seed, so it leaves you with an empty database. Use the command above instead.
Run the app:
composer dev # serve + queue:listen + pail + vite, together
queue:listen matters: availability slot generation is dispatched to a queue
(GenerateMentorSlotsJob). Without a worker, edits to rules or off-days appear to do
nothing.
Default accounts
Every seeded account uses the password 12345678.
Admin
| Password | Role | Notes | |
|---|---|---|---|
admin@demo.com |
12345678 |
admin |
All 15 permissions. No profile record. Approves the demo mentors |
Mentors β approved
Fully set up and bookable: session types, weekday availability, certification, completed onboarding.
| Password | Name | Notes | |
|---|---|---|---|
mentor.sarah@demo.com |
12345678 |
Sarah Johnson | Owns all community and course data β start here for Communities/Courses |
mentor.david@demo.com |
12345678 |
David Chen | Sessions + availability only |
mentor.emily@demo.com |
12345678 |
Emily Rodriguez | Sessions + availability only |
Mentor β pending approval
| Password | Name | Notes | |
|---|---|---|---|
mentor.pending@demo.com |
12345678 |
John Pending | approval_status: pending. Use to exercise the admin approval flow and gating on unapproved mentors. No session types, availability, or certification |
Mentees
| Password | Name | Notes | |
|---|---|---|---|
mentee.alex@demo.com |
12345678 |
Alex Thompson | Laravel Builders, level 3 (450 XP) β clears the level-3 course gate |
mentee.priya@demo.com |
12345678 |
Priya Patel | In both communities β Laravel Builders level 1, Career Switchers level 4 |
mentee.marcus@demo.com |
12345678 |
Marcus Williams | Career Switchers, level 1 β below the level-2 gate, for testing locked content |
Unverified
| Password | Name | Notes | |
|---|---|---|---|
unverified@demo.com |
12345678 |
Unverified User | email_verified_at is null and no role is assigned. For testing verification gating |
What's seeded under each user
Roles and permissions
RolePermissionSeeder creates 15 permissions and 3 roles.
| Role | Permissions |
|---|---|
admin |
All 15 |
mentor |
manage-mentor-profile, view-sessions, manage-availability, view-mentors, submit-onboarding |
mentee |
manage-mentee-profile, book-sessions, view-mentors, submit-onboarding |
Full permission list: manage-mentor-profile, view-sessions, manage-availability,
manage-mentee-profile, book-sessions, manage-users, approve-mentors, manage-roles,
manage-permissions, manage-settings, view-reports, manage-platform, view-users,
view-mentors, submit-onboarding.
Session types β Sarah, David, Emily (2 each, 6 total)
| Title | Duration | Buffer | Price | Follow-ups |
|---|---|---|---|---|
| Intro Call | 30 min | 10 min | Free | 0 |
| Deep Dive Mentoring | 60 min | 15 min | $75.00 | 2, every 7 days (Β±2 days flex) |
Both are regular_weekly, max_capacity: 1 (one-on-one), USD. Set max_capacity > 1 on a
session type to make it a group session β several mentees then book seats on one slot and
share a single meeting room. See booking-api.md.
Availability β Sarah, David, Emily (5 rules each, 15 total)
One regular_weekly rule per weekday (MonβFri), 09:00β17:00, applying to all session
types (session_type_id: null), valid from the start of the current month with no end date.
See Availability.
Slots and bookings
MentorSessionSeeder fills the next calendar month β 3 slots per weekday per mentor at
10:00, 14:00, 16:00, alternating between the two session types. Roughly ~66 slots per
mentor.
Each slot then has a 45% chance of being booked by a random mentee. Deep Dive bookings also reserve their 2 follow-up slots; a booking is skipped entirely if a follow-up window can't be filled.
Non-deterministic. Booking count, which mentee books what, and booking status (
requested/confirmed/paid) are randomized per run. Confirmed and paid bookings get a meeting room on their slot; requested ones don't. Note the API only exposesmeetingUrlonce a booking is settled, so a paid session type sitting atconfirmedstill readsnulluntil it reachespaid. Don't write tests against these β use factories.
Communities β all owned by Sarah
| Name | Slug | Pricing | Members |
|---|---|---|---|
| Laravel Builders | laravel-builders |
Free | Alex (L3), Priya (L1) |
| Career Switchers | career-switchers |
$19.00 subscription | Priya (L4), Marcus (L1) |
Both use the same level curve: L2 = 100 XP Β· L3 = 300 Β· L4 = 600 Β· L5 = 1000.
Courses β all owned by Sarah
| Title | Visibility | Price | Community | Gate |
|---|---|---|---|---|
| PHP Fundamentals | Public | $29.00 | β | β |
| Eloquent Deep Dive | Community-only | Free | Laravel Builders | Level 3 |
| From Junior to Senior Engineer | Community-only | Free | Laravel Builders + Career Switchers | Level 2 |
From Junior to Senior Engineer costs $9.00 for Career Switchers members
(SpecificCommunity audience pricing) but is free for Laravel Builders β the case to use
when testing per-community pricing.
The two community courses each have 2 modules (Getting Started, then Advanced Practice
locked at the gate level) with 2 text lessons apiece. The first lesson of the ungated module
is marked preview.
Gating combinations worth knowing: Alex (L3) can open everything in Laravel Builders; Marcus (L1) is below the L2 gate in Career Switchers; Priya sits on either side depending on which community you look at.
Reference data
- Expertise areas β 58 areas with ~406 skills
- Countries/states β loaded from
public/sql/countries.sqlandstates.sql - Platform settings β defaults via
PlatformSettingSeeder
Not seeded
Chat threads, feed posts, subscriptions, and course enrollments have no seeder β factories exist but are test-only. Create these through the API, or use the factories in tests.
Re-running seeders
Prefer php artisan migrate:fresh --seed. Several seeders are not idempotent, so a plain
db:seed on an already-seeded database compounds data:
| Seeder | On re-run |
|---|---|
ExpertiseAreaSeeder |
Adds another full 58 areas + ~406 skills. Slugs are suffixed with uniqid(), so nothing collides and nothing dedupes |
DemoDataSeeder |
Users and profiles are safe (firstOrCreate), but appends 3β5 more expertise-area links per mentor every time |
MentorSessionSeeder |
Slots are safe, but creates additional bookings against remaining available slots. Also month-relative β running in a new month seeds a disjoint set |
RolePermissionSeeder, AdminSeeder, PlatformSettingSeeder, SessionTypeSeeder, CommunityCourseSeeder |
Safe β idempotent |
CountryStateSeeder |
Safe β truncates before loading |
Run order
Seeders depend on each other and must run in DatabaseSeeder order:
RolePermissionSeederβ 2.AdminSeederβ 3.PlatformSettingSeederβExpertiseAreaSeederβ 5.CountryStateSeederβ 6.DemoDataSeederβSessionTypeSeederβ 8.MentorSessionSeederβ 9.CommunityCourseSeeder
Running one alone out of order mostly warns and returns rather than crashing β e.g.
SessionTypeSeeder prints No approved mentors found. Run DemoDataSeeder first.
Verify the setup
php artisan test # expect 620 passed
php artisan route:list --path=api/v1
Log in and confirm you get a token:
curl -X POST http://meetyy-api.test/api/v1/login \
-H "Accept: application/json" \
-d "email=mentor.sarah@demo.com&password=12345678"
Then use the token as Authorization: Bearer {token} β for example against
GET /api/v1/mentor/availability-rules, which should return Sarah's 5 weekday rules.