Version: 2.0
Last Updated: November 10, 2025
A modern, role-based diamond inventory and sharing system for manufacturers (admins), resellers (clients), and their end customers. Features secure invite links, read-only customer views, and full diamond management capabilities.
- Modern, responsive design with gradient backgrounds
- Hero section with CTAs for client sign-in
- Featured diamond catalog preview
- Contact information and partner program details
- Mobile-responsive navigation with Alpine.js
Three distinct user roles:
-
Admin (Manufacturer) - Full system access
- Manage all diamonds, staff, and masters
- View all analytics and reports
- Configure system settings
- Access all client invites
-
Client (Reseller) - Limited business access
- Browse available diamond inventory
- Create secure invite links for customers
- Manage own invites (view, revoke)
- Track invite analytics (views, access count)
-
Customer (Read-Only) - Invite-based access
- View diamonds shared via invite link
- Read-only diamond specifications
- Time-limited access (configurable expiry)
- No login required (token-based)
- Secure Token Generation: 64-character hex tokens using
random_bytes() - Time-Limited Access: Configurable expiry (1-90 days)
- Diamond Selection: Multi-select diamonds to share
- Customer Info: Optional name and contact tracking
- Revocation: Clients can revoke invites anytime
- Analytics: Track views, access count, last accessed time
- Rate Limiting: Configurable daily invite creation limits
- Modern card-based diamond grid
- Advanced filtering (search, shape, status)
- Detailed diamond modals with full specifications
- One-click invite creation from any diamond
- Responsive design with Tailwind CSS
- Prepared SQL statements (PDO) for all queries
- Role-based page access control
- Token validation and expiry checks
- Rate limiting on invite creation
- Activity logging (admin actions)
- HTTPS recommended for production
- Web Server: Apache (WAMP, XAMPP, or LAMP)
- PHP: 7.4 or higher
- MySQL: 5.7 or higher (or MariaDB 10.3+)
- Composer: For dependency management (already included in
/vendor) - PHP Extensions: PDO, mysqli, mbstring, json
# Navigate to your web server directory
cd c:\wamp64\www
# Or for Linux/Mac
cd /var/www/html
# The project should be in ds_diamonds folderEdit config.php with your database credentials:
$servername = "localhost";
$username = "root"; // Your MySQL username
$password = ""; // Your MySQL password
$dbname = "ds_diamonds_db"; // Database nameCREATE DATABASE IF NOT EXISTS ds_diamonds_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;Import the base SQL schema from SQL Commads to create all tables..txt:
# Via MySQL CLI
mysql -u root -p ds_diamonds_db < "SQL Commads to create all tables..txt"
# Or use phpMyAdmin:
# 1. Open phpMyAdmin
# 2. Select ds_diamonds_db database
# 3. Go to Import tab
# 4. Choose the SQL file and executeImport migrations.sql to add new role-based features:
mysql -u root -p ds_diamonds_db < migrations.sql
# Or via phpMyAdmin (same process as above)This migration adds:
rolecolumn tostafftable (admin/client)client_idforeign key tocustomerstableinvitestable for secure sharinginvite_access_logtable for analyticssystem_settingstable for configuration- Additional timestamp columns to existing tables
- Access the landing page:
http://localhost/ds_diamonds/landing.php - Access login page:
http://localhost/ds_diamonds/index.php - Default admin credentials (set in migration):
- UserID: (check your staff table, usually ID 1)
- Password: (your existing password)
- Role: Will be set to 'admin' automatically for first user
After running migrations, ensure your main account is set as admin:
UPDATE staff SET role = 'admin' WHERE id = 1;INSERT INTO staff (client_name, name, user_id, password, status, role)
VALUES ('Test Reseller Co', 'John Client', 'testclient', 'password123', 'Enable', 'client');Login as admin and set these in the database (or create an admin UI later):
-- Update base URL for invite links
UPDATE system_settings
SET setting_value = 'http://localhost/ds_diamonds'
WHERE setting_key = 'app_base_url';
-- Update default invite expiry
UPDATE system_settings
SET setting_value = '7'
WHERE setting_key = 'invite_default_expiry_days';
-- Update rate limit
UPDATE system_settings
SET setting_value = '20'
WHERE setting_key = 'invite_max_per_client_daily';ds_diamonds/
βββ landing.php # Public landing page (NEW)
βββ index.php # Login page (UPDATED with role support)
βββ config.php # Database configuration
βββ auth_check.php # RBAC helper functions (NEW)
β
βββ Client Pages (NEW)
βββ client_dashboard.php # Client diamond browser
βββ client_invite_create.php # Create invite form
βββ client_invites.php # Manage invites
βββ invite_view.php # Public invite view (no auth)
β
βββ Admin Pages (EXISTING)
βββ home.php # Dashboard
βββ diamond_master.php # Diamond CRUD (UPDATED with customer view)
βββ staff_master.php # Staff management
βββ customer_master.php # Customer management
βββ shared_links.php # Legacy sharing system
βββ config_generic.php # System configuration
β
βββ Master Pages (EXISTING)
βββ shape_master.php
βββ color_master.php
βββ clarity_master.php
βββ cut_master.php
βββ polish_master.php
βββ symmetry_master.php
β
βββ Components (UPDATED)
βββ header.php # Page header with auth check
βββ sidebar.php # Navigation (UPDATED with role-based menus)
βββ footer.php # Page footer
β
βββ Database
βββ migrations.sql # New role-based schema (NEW)
βββ SQL Commads to create all tables..txt # Base schema
β
βββ Assets
βββ assets/images/shapes/ # Diamond shape SVGs
β
βββ vendor/ # Composer dependencies
- Login with admin credentials β Redirected to
home.php - Manage diamonds via
diamond_master.php - Add/edit clients via
staff_master.php(role = 'client') - View system configuration
- Access all master data tables
- View analytics and reports
- Login with client credentials β Redirected to
client_dashboard.php - Browse available diamonds (grid view with filters)
- Click "Create Invite Link" on any diamond
- Fill form: customer name, select diamonds, set expiry
- Copy generated invite URL
- Share URL with customer (email, SMS, WhatsApp, etc.)
- Track invite analytics in
client_invites.php - Revoke invite if needed
- Receive invite URL from reseller (e.g.,
http://domain.com/ds_diamonds/invite_view.php?token=abc123...) - Open URL in browser (no login required)
- View shared diamonds in read-only mode
- See full specifications, certifications
- Contact reseller to purchase (in-person transaction)
- URL expires after configured days
Edit system_settings table or create a UI to manage:
| Setting Key | Default | Description |
|---|---|---|
app_base_url |
http://localhost/ds_diamonds |
Base URL for generating invite links |
invite_default_expiry_days |
7 |
Default days before invite expires |
invite_max_per_client_daily |
20 |
Max invites a client can create per day |
app_name |
DS Diamonds |
Application name |
app_tagline |
Exquisite diamonds, verified authenticity |
Tagline |
Clients can choose 1-90 days when creating invites. Default is set in settings.
Prevent abuse by limiting daily invite creation per client. Adjustable in system_settings.
URL: http://localhost/ds_diamonds/index.php
Role: Client (toggle)
UserID: (your admin user_id)
Password: (your password)
URL: http://localhost/ds_diamonds/index.php
Role: Client (toggle)
UserID: testclient
Password: password123
URL: http://localhost/ds_diamonds/index.php
Role: Customer (toggle)
Customer Name: (from customers table)
Contact Number: (from customers table)
- Login as client
- Navigate to "Create Invite"
- Select 1-3 diamonds
- Set expiry to 1 day
- Submit and copy invite link
- Open invite link in incognito window
- Verify read-only diamond view
- Wait 1 day and verify expiry message
- Login as client
- Create 20 invites in quick succession
- Attempt 21st invite β should show error
-
HTTPS Only
- Use SSL certificate (Let's Encrypt recommended)
- Update
app_base_urltohttps://in settings
-
Strong Passwords
- Use password hashing (bcrypt/Argon2) instead of plaintext
- Update login logic in
index.phpto usepassword_verify()
Example:
// When creating user $hashed = password_hash($password, PASSWORD_BCRYPT); // When logging in if (password_verify($input_password, $user['password'])) { // Login successful }
-
Database Security
- Use non-root MySQL user
- Grant only necessary permissions
- Keep
config.phpoutside web root if possible
-
Environment Variables
- Move sensitive config to
.envfile - Use
vlucas/phpdotenvpackage (already in vendor) - Add
.envto.gitignore
- Move sensitive config to
-
Session Security
- Add to
config.php:
ini_set('session.cookie_httponly', 1); ini_set('session.cookie_secure', 1); // If using HTTPS ini_set('session.use_strict_mode', 1);
- Add to
-
SQL Injection Prevention
- Already implemented: All queries use prepared statements
- Never concatenate user input into SQL
-
XSS Prevention
- Already implemented: All output uses
htmlspecialchars()viah()helper - Continue using
h()function for all user-generated content
- Already implemented: All output uses
-
Rate Limiting
- Consider adding IP-based rate limiting for login attempts
- Use libraries like
symfony/rate-limiter
Primary table for invite system.
| Column | Type | Description |
|---|---|---|
id |
INT | Primary key |
client_id |
INT | FK to staff table |
token |
VARCHAR(64) | Unique secure token |
customer_name |
VARCHAR(255) | Optional customer name |
customer_contact |
VARCHAR(100) | Optional contact info |
note |
TEXT | Private note for client |
diamonds_shared |
JSON | Array of diamond IDs |
expires_at |
DATETIME | Expiration timestamp |
created_at |
TIMESTAMP | Creation timestamp |
used |
TINYINT(1) | 0=active, 1=revoked |
access_count |
INT | Number of times viewed |
last_accessed_at |
DATETIME | Last view timestamp |
Tracks each invite access for analytics.
| Column | Type | Description |
|---|---|---|
id |
INT | Primary key |
invite_id |
INT | FK to invites |
accessed_at |
TIMESTAMP | Access time |
ip_address |
VARCHAR(45) | Visitor IP |
user_agent |
TEXT | Browser info |
Key-value store for configuration.
| Column | Type | Description |
|---|---|---|
id |
INT | Primary key |
setting_key |
VARCHAR(100) | Unique key |
setting_value |
TEXT | Value |
description |
TEXT | Usage description |
updated_at |
TIMESTAMP | Last update |
Added role column for RBAC.
ALTER TABLE staff
ADD COLUMN role ENUM('admin', 'client') NOT NULL DEFAULT 'client';Added client_id foreign key.
ALTER TABLE customers
ADD COLUMN client_id INT DEFAULT NULL,
ADD FOREIGN KEY (client_id) REFERENCES staff(id) ON DELETE CASCADE;- Framework: Tailwind CSS (via CDN)
- Icons: Font Awesome 6.4.0
- Fonts: Inter (body), Playfair Display (headings)
- JS Library: Alpine.js 3.x (lightweight reactivity)
--primary: #7b2ff7 (purple)
--secondary: #f83077 (pink)
--dark: #0f172a (slate)
--gradient: linear-gradient(135deg, #7b2ff7, #f83077)- Cards: Rounded, shadow-md, hover effects
- Modals: Alpine.js powered, overlay with backdrop
- Forms: Rounded inputs with focus rings
- Buttons: Gradient backgrounds, hover animations
- Tables: Striped rows, hover states
- Mobile: < 768px
- Tablet: 768px - 1024px
- Desktop: > 1024px
If you're upgrading from an older version:
mysqldump -u root -p ds_diamonds_db > backup_$(date +%Y%m%d).sql-- Set your main account as admin
UPDATE staff SET role = 'admin' WHERE user_id = 'your_admin_userid';
-- Set all others as clients
UPDATE staff SET role = 'client' WHERE user_id != 'your_admin_userid';-- Example: Link all customers to a specific client
UPDATE customers SET client_id = 1 WHERE client_id IS NULL;- Test admin login and navigation
- Test client login and dashboard
- Create a test invite and verify access
- Check legacy pages still work (diamond_master.php, etc.)
Solution: Check if user has role = 'client' in staff table and status = 'Enable'.
SELECT id, name, user_id, role, status FROM staff WHERE user_id = 'your_userid';Solution:
- Check token format (should be 64 hex characters)
- Verify invite exists in database
- Check if invite is expired or revoked
SELECT * FROM invites WHERE token = 'your_token';Solution: Update system setting:
UPDATE system_settings
SET setting_value = 'https://yourdomain.com/ds_diamonds'
WHERE setting_key = 'app_base_url';Solution: Ensure session has role = 'client'. Clear browser cache and re-login.
Solution: Check that shape SVG files exist in assets/images/shapes/. If missing, add placeholder images or update to use Font Awesome icons only.
Solution: Ensure auth_check.php is included at top of all protected pages:
require_once 'auth_check.php';Potential features for future development:
- Email notifications when invites are accessed
- QR code generation for invites
- Advanced analytics dashboard for clients
- Diamond comparison tool
- Wishlist/favorites for customers
- Multi-language support
- Dark mode toggle
- PDF export of diamond details
- WhatsApp/SMS integration for invite sharing
- Password reset via email
- Two-factor authentication (2FA)
- API endpoints for mobile app
- Real-time inventory sync
- Client branding (white-label invites)
- Advanced search with faceted filters
For issues or questions:
- Check this README first
- Review code comments in key files
- Check browser console for JS errors
- Check PHP error logs:
c:\wamp64\logs\php_error.log - Verify database schema matches migrations
Β© 2025 DS Diamonds. All rights reserved.
This is proprietary software. Unauthorized copying, distribution, or modification is prohibited.
Built with:
- PHP 7.4+
- MySQL 5.7+
- Tailwind CSS 3.x
- Alpine.js 3.x
- Font Awesome 6.4.0
- PhpSpreadsheet (for Excel operations)
- HTML Purifier (for security)
Developed by: DS Diamonds Development Team
Last Updated: November 10, 2025
Version: 2.0.0
- Install WAMP/XAMPP and start Apache + MySQL
- Create
ds_diamonds_dbdatabase - Update
config.phpwith database credentials - Import
SQL Commads to create all tables..txt - Import
migrations.sql - Set first user as admin role
- Update
app_base_urlin system_settings - Test admin login
- Create test client user
- Test client login
- Create test invite
- Open invite link and verify
- Configure HTTPS for production
- Implement password hashing
- Set up backups
- Deploy! π
Happy Diamond Sharing! π