Skip to content

Commit 8d33c4d

Browse files
authored
2.7.8
2.7.8
2 parents 1b944ea + 09c35e5 commit 8d33c4d

11 files changed

Lines changed: 3165 additions & 23 deletions

File tree

.github/copilot-instructions.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Cloudlog AI Coding Agent Instructions
2+
3+
## Project Overview
4+
Cloudlog is a self-hosted **PHP web application** for amateur radio contact logging. Built on **CodeIgniter 3** MVC framework with Bootstrap 5 frontend, HTMX for AJAX interactions, and jQuery for enhanced functionality.
5+
6+
**Stack**: PHP 7.4+ (8.2 compatible), MySQL 5.7+, Apache/Nginx, CodeIgniter 3
7+
8+
UI: Default Bootstrap styling (no custom theme by default).
9+
10+
## Architecture
11+
12+
### MVC Structure (CodeIgniter 3)
13+
- **Controllers** (`application/controllers/`): Extend `CI_Controller`, handle authentication via `user_model->validate_session()`
14+
- **Models** (`application/models/`): Extend `CI_Model`, handle database operations (e.g., `Logbook_model`, `Stations`)
15+
- **Views** (`application/views/`): PHP templates with Bootstrap 5 classes, loaded via `$this->load->view()`
16+
- **Libraries** (`application/libraries/`): Custom classes like `Qra` (gridsquare calculations), `optionslib` (settings)
17+
18+
### Key Patterns
19+
```php
20+
// Controllers always check authentication first
21+
$this->load->model('user_model');
22+
if ($this->user_model->validate_session() == 0) {
23+
redirect('user/login');
24+
}
25+
26+
// Authorization levels: authorize(2) for users, authorize(99) for admins
27+
if (!$this->user_model->authorize(2)) {
28+
$this->session->set_flashdata('notice', 'You\'re not allowed to do that!');
29+
redirect('dashboard');
30+
}
31+
```
32+
33+
### Configuration
34+
- **Config files**: `application/config/config.php` (app settings), `database.php` (DB credentials)
35+
- Sample files: `config.sample.php`, `database.sample.php` - copy and customize for local setup
36+
- Environment: Set in `index.php` - `define('ENVIRONMENT', 'development')` shows profiler
37+
- Version: Defined in `config.php` as `$config['app_version'] = "2.4.5"`
38+
39+
## Frontend Integration
40+
41+
### HTMX Usage (Primary AJAX Method)
42+
HTMX is the **preferred** method for dynamic content loading. Views use `hx-get`, `hx-post`, `hx-target` attributes:
43+
```php
44+
<!-- Auto-refreshing component -->
45+
<div id="qso-last-table" hx-get="<?php echo site_url('/qso/component_past_contacts'); ?>"
46+
hx-trigger="load, every 5s">
47+
</div>
48+
49+
<!-- Form submission -->
50+
<form hx-post="<?php echo site_url('logbooks/save_publicslug/'); ?>"
51+
hx-target="#publicSlugForm">
52+
```
53+
54+
### HTMX In Practice
55+
- Previous QSOs widget:
56+
- View snippet (auto-refresh):
57+
```php
58+
<div id="qso-last-table" hx-get="<?php echo site_url('/qso/component_past_contacts'); ?>" hx-trigger="load, every 5s"></div>
59+
```
60+
- Controller endpoint: `application/controllers/Qso.php::component_past_contacts()` loads `application/views/qso/components/previous_contacts.php` with `$this->logbook_model->last_custom('5')`.
61+
62+
- Save Public Slug form:
63+
- View snippet:
64+
```php
65+
<form hx-post="<?php echo site_url('logbooks/save_publicslug/'); ?>" hx-target="#publicSlugForm">
66+
<input type="hidden" name="logbook_id" value="<?php echo $logbook_id; ?>">
67+
<input type="text" name="public_slug" required>
68+
<button type="submit" class="btn btn-primary">Save</button>
69+
</form>
70+
```
71+
- Controller endpoint: `application/controllers/Logbooks.php::save_publicslug()` validates `public_slug` (`required|alpha_numeric`) and persists via `logbooks_model`.
72+
73+
### Assets
74+
- **Most assets**: Live under `assets/`; core includes are wired via `application/views/interface_assets/header.php` and `application/views/interface_assets/footer.php`.
75+
- **CSS**: `assets/css/` - Bootstrap themes, custom overrides in `themes/*/overrides.css`
76+
- **JS**: `assets/js/` - jQuery, HTMX (`htmx.min.js`), Leaflet maps, custom logic
77+
- **Icons**: Font Awesome (via `assets/fontawesome/`)
78+
79+
## Database
80+
81+
### Migrations
82+
Database schema managed via **CodeIgniter migrations** (`application/migrations/`):
83+
- Sequential numbered files: `001_add_lotw_credentials.php``232_tag_2_7_7.php`
84+
- Each extends `CI_Migration` with `up()` method
85+
- Run via: `php index.php migrate` or through admin interface
86+
87+
### Key Tables
88+
- `TABLE_HRD_CONTACTS_V01`: QSO log (configured in `config.php`)
89+
- `station_profile`: Station locations and settings
90+
- `station_logbooks`: Logbook definitions
91+
- `station_logbooks_entity`: Logbook-location relationships
92+
93+
## Development Workflows
94+
95+
### Docker Development Setup
96+
```bash
97+
# Start environment (web + db services)
98+
docker-compose up
99+
100+
# Access: http://localhost/
101+
# DB host in Docker: 'db' (service name, not localhost)
102+
```
103+
104+
**Configuration**: Copy `.env.sample` to `.env` and adjust DB settings before starting.
105+
106+
### Testing
107+
**Cypress** end-to-end tests (`cypress/e2e/`):
108+
```bash
109+
# Install & run tests
110+
npm install cypress
111+
npx cypress run
112+
113+
# Tests require Docker containers running
114+
docker-compose up -d
115+
```
116+
117+
Tests validate: login flows, station creation, logbook operations, version checks.
118+
119+
### Common Tasks
120+
- **Enable profiler**: Set `ENVIRONMENT = 'development'` in `index.php`
121+
- **Routing**: CI3 maps `/controller/method` to `Controller::method` by default; `application/config/routes.php` is typically left at its default (`default_controller = 'dashboard'`). Only edit routes for custom remaps.
122+
- **Base URL helpers**: Use `site_url()` and `base_url()` in views/controllers
123+
124+
## Where To Start (New Features)
125+
- **Controller**: Add `application/controllers/MyFeature.php` extending `CI_Controller`. In `__construct()` or method start, load `user_model` and enforce `validate_session()`/`authorize()` as needed. Return views via `$this->load->view()`.
126+
- **Model**: Add `application/models/Myfeature_model.php` for DB access. Use CI Query Builder. Inject via `$this->load->model('myfeature_model')`.
127+
- **View**: Create `application/views/myfeature/*.php`. Include header/footer (`interface_assets/header` and `interface_assets/footer`). Prefer HTMX (`hx-get`/`hx-post`) for async UI.
128+
- **Migrations**: For schema changes, add `application/migrations/NNN_description.php` and run `php index.php migrate` (or use the admin UI). Keep IDs sequential.
129+
- **Routing note**: New endpoints are reachable as `/index.php/myfeature/method` (and usually `/myfeature/method` with proper web server config); no routes entry required unless you need a custom URI.
130+
131+
## Domain-Specific Context
132+
133+
### Amateur Radio Concepts
134+
- **Gridsquare/Locator**: Maidenhead grid system for location (e.g., `IO87JP`)
135+
- **QSO**: Radio contact/log entry
136+
- **DXCC**: Country entities for award tracking
137+
- **ADIF**: Amateur Data Interchange Format for import/export
138+
- **LoTW/eQSL**: Electronic QSL card confirmation systems
139+
140+
### Libraries & Helpers
141+
- **Qra library** (`application/libraries/Qra.php`): Calculate bearings, distances, gridsquare conversions
142+
- **qra2latlong()**: Global function (defined in `Qra.php`) converts Maidenhead to coordinates
143+
144+
## Code Conventions
145+
146+
### Controllers
147+
- Load models in `__construct()` or method start
148+
- Use flashdata for user messages: `$this->session->set_flashdata('notice', 'Message')`
149+
- Redirect after POST: `redirect('controller/method')`
150+
151+
### Views
152+
- Header/footer: `$this->load->view('interface_assets/header', $data)` + `footer.php`
153+
- JavaScript globals defined in `footer.php`: `base_url`, `site_url`, `my_call`
154+
- Language strings: `<?php echo lang('key'); ?>` (files in `application/language/`)
155+
156+
### Security
157+
- Input sanitization: `$this->security->xss_clean($input)`
158+
- Prevent direct access: `if (!defined('BASEPATH')) exit('No direct script access allowed');`
159+
- SQL: Use Query Builder or prepared statements (handled by CI3 models)
160+
161+
## Pull Request Guidelines
162+
- **Target branch**: `dev` (PRs to `main` will be rejected)
163+
- **One feature per PR**: No multi-feature or bundled bug fixes
164+
- **Comment code**: Explain non-obvious logic
165+
- **Test coverage**: Run Cypress tests before submitting
166+
- **Description**: Clearly state what the PR does and why it's needed
167+
168+
## Common Pitfalls
169+
- **Don't use `&&` in PowerShell commands** - use `;` to chain commands
170+
- **Docker DB host**: Use service name `db`, not `localhost` or `127.0.0.1`
171+
- **Config files**: Never commit `config.php` or `database.php` (use `.sample` versions as templates)
172+
- **Base URL**: Must be set correctly in `config.php` for site to work properly

application/config/migration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
|
2323
*/
2424

25-
$config['migration_version'] = 232;
25+
$config['migration_version'] = 233;
2626

2727
/*
2828
|--------------------------------------------------------------------------

0 commit comments

Comments
 (0)