This commit is contained in:
2026-04-25 16:55:49 +02:00
parent ae0681a016
commit 29b13ccc70
19 changed files with 248 additions and 14 deletions

29
.paul/PROJECT.md Normal file
View File

@@ -0,0 +1,29 @@
# Project: globelus.pl
## Description
Portal ogloszeniowy do publikacji i wyszukiwania ofert pracy, z panelami dla kandydatow i pracodawcow oraz filtrowaniem ofert po wielu kryteriach.
## Core Value
Kandydaci szybko znajduja dopasowane oferty pracy, a pracodawcy latwo docieraja do odpowiednich kandydatow.
## Requirements
### Must Have
- [To be defined during planning]
### Should Have
- [To be defined during planning]
### Nice to Have
- [To be defined during planning]
## Constraints
- [To be identified during planning]
## Success Criteria
- Kandydaci szybko znajduja dopasowane oferty pracy, a pracodawcy latwo docieraja do odpowiednich kandydatow.
- [To be refined during planning]
---
*Created: 2026-04-25 16:39*

23
.paul/ROADMAP.md Normal file
View File

@@ -0,0 +1,23 @@
# Roadmap: globelus.pl
## Overview
Rozwoj projektu obejmuje stabilizacje kluczowych flow ofert pracy, poprawy jakosci danych i filtrowania, a nastepnie kolejne usprawnienia UX oraz procesu publikacji i aplikowania.
## Current Milestone
**v0.1 Initial Release** (v0.1.0)
Status: Not started
Phases: 0 of TBD complete
## Phases
| Phase | Name | Plans | Status | Completed |
|-------|------|-------|--------|-----------|
| 1 | TBD | TBD | Not started | - |
## Phase Details
Phases will be defined during `$paul-plan`.
---
*Roadmap created: 2026-04-25 16:39*

49
.paul/STATE.md Normal file
View File

@@ -0,0 +1,49 @@
# Project State
## Project Reference
See: .paul/PROJECT.md (updated 2026-04-25 16:39)
**Core value:** Kandydaci szybko znajduja dopasowane oferty pracy, a pracodawcy latwo docieraja do odpowiednich kandydatow.
**Current focus:** Project initialized - ready for planning
## Current Position
Milestone: v0.1 Initial Release
Phase: Not yet defined
Plan: None yet
Status: Ready to create roadmap and first PLAN
Last activity: 2026-04-25 16:39 - Project initialized
Progress:
- Milestone: [----------] 0%
## Loop Position
Current loop state:
```
PLAN --> APPLY --> UNIFY
o o o [Ready for first PLAN]
```
## Accumulated Context
### Decisions
None yet.
### Deferred Issues
None yet.
### Blockers/Concerns
None yet.
## Session Continuity
Last session: 2026-04-25 16:39
Stopped at: Project initialization complete
Next action: Run $paul-plan to define phases and first plan
Resume file: .paul/PROJECT.md
---
*STATE.md - Updated after every significant action*

34
.paul/config.md Normal file
View File

@@ -0,0 +1,34 @@
# Project Config
**Project:** globelus.pl
**Created:** 2026-04-25 16:39
## Project Settings
```yaml
project:
name: globelus.pl
version: 0.0.0
```
## Integrations
### SonarQube
```yaml
sonarqube:
enabled: false
reason: "Skipped during init"
```
## Preferences
```yaml
preferences:
auto_commit: false
verbose_output: false
```
---
*Config created: 2026-04-25 16:39*

5
.paul/docs/API.md Normal file
View File

@@ -0,0 +1,5 @@
# API
> Endpointy, kontrakty request/response, autentykacja.
> Uzupelnij gdy projekt bedzie udostepnial API.

View File

@@ -0,0 +1,5 @@
# Architecture
> Struktura klas, modulow, przeplywow i zaleznosci w projekcie.
> Uzupelnij po pierwszej fazie implementacji.

5
.paul/docs/DB_SCHEMA.md Normal file
View File

@@ -0,0 +1,5 @@
# Database Schema
> Schemat bazy danych - tabele, kolumny, FK, indeksy.
> Uzupelnij gdy projekt bedzie korzystac z bazy danych.

5
.paul/docs/DECISIONS.md Normal file
View File

@@ -0,0 +1,5 @@
# Architecture Decision Records
> Kluczowe decyzje techniczne i ich uzasadnienia.
> Dodawaj wpisy recznie, gdy podejmujesz istotne decyzje architektoniczne.

5
.paul/docs/STACK.md Normal file
View File

@@ -0,0 +1,5 @@
# Stack
> Stack technologiczny, wersje, zaleznosci, srodowisko.
> Uzupelnij po inicjalizacji projektu.

View File

@@ -0,0 +1,5 @@
# Tech Changelog
> Chronologiczny log zmian technicznych - co i dlaczego.
> Aktualizowany automatycznie po kazdej fazie PAUL.

5
.paul/docs/TODO.md Normal file
View File

@@ -0,0 +1,5 @@
# TODO
> Luzny parking pomyslow, rzeczy do sprawdzenia i pomyslow na pozniej.
> Nie wymaga formalnosci.

3
.vscode/ftp-kr.json vendored
View File

@@ -15,6 +15,7 @@
"/.vscode",
"/.serena",
"/.claude",
"CLAUDE.md"
"CLAUDE.md",
".paul"
]
}

33
CLAUDE.md Normal file
View File

@@ -0,0 +1,33 @@
# Projektowe zasady dla globelus.pl
## Stack
- **Jezyk:** PHP
- **Framework:** Wlasny system MVC + szablony PHP
- **Wersja:** legacy/custom
## Zasady kodu
- Stosuj PSR-12 dla formatowania kodu PHP.
- Nazewnictwo: PascalCase dla klas, camelCase dla metod, snake_case dla pol DB.
- Unikaj zagniezdzen > 3 poziomy; wydzielaj metody pomocnicze.
- Komentarze tylko gdy wyjasniaja "dlaczego", nie "co".
## Baza danych
- Schemat dokumentowany w `.paul/docs/DB_SCHEMA.md`.
- Kazda zmiana schematu wymaga migracji lub udokumentowanej procedury SQL.
- Nie modyfikuj historycznych migracji/skryptow bez uzasadnienia.
## Testy
- Ustal i udokumentuj komende testowa dla projektu (brak standardowej konfiguracji testow).
## Dokumentacja
- Dokumentacja techniczna w `.paul/docs/`.
- Przy kazdej zmianie aktualizuj odpowiednie pliki docs.
- `TECH_CHANGELOG.md` aktualizowany po kazdej fazie.
## Wdrazanie
- Ustal i dopisz procedure deploy dla produkcji/staging.
## UI/Frontend
- Projekt korzysta z szablonow PHP i assets statycznych; utrzymuj spojnosc z istniejacym stylem.
- Zmiany UX w listingu ofert testuj na flow filtrowania i paginacji.

View File

@@ -331,14 +331,24 @@ class GlobelusAdverts
if ( $values['keyword'] )
$filtr .= 'AND ( '
. 'title_nopl LIKE :title_nopl '
. 'OR '
. 'title LIKE :title '
. 'OR '
. 'firm_name_profile_nopl LIKE :firm_name_profile_nopl '
. 'OR '
. 'firm_name_profile LIKE :firm_name_profile '
. 'OR '
. 'text_nopl LIKE :text_nopl '
. 'OR '
. 'text LIKE :text '
. 'OR '
. 'country_nopl LIKE :country_nopl '
. 'OR '
. 'country LIKE :country '
. 'OR '
. 'city_nopl LIKE :city_nopl '
. 'OR '
. 'city LIKE :city '
. ') ';
if ( is_array( $values['countries'] ) and count( $values['countries'] ) == 1 and $values['countries'][0] == 75 )
@@ -453,7 +463,12 @@ class GlobelusAdverts
':title_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%',
':text_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%',
':country_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%',
':city_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%'
':city_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%',
':title' => '%' . trim( (string)$values['keyword'] ) . '%',
':firm_name_profile' => '%' . trim( (string)$values['keyword'] ) . '%',
':text' => '%' . trim( (string)$values['keyword'] ) . '%',
':country' => '%' . trim( (string)$values['keyword'] ) . '%',
':city' => '%' . trim( (string)$values['keyword'] ) . '%'
] ) -> fetch();
}
catch ( \Throwable $t )
@@ -493,14 +508,24 @@ class GlobelusAdverts
if ( $values['keyword'] )
$filtr .= 'AND ( '
. 'title_nopl LIKE :title_nopl '
. 'OR '
. 'title LIKE :title '
. 'OR '
. 'firm_name_profile_nopl LIKE :firm_name_profile_nopl '
. 'OR '
. 'firm_name_profile LIKE :firm_name_profile '
. 'OR '
. 'text_nopl LIKE :text_nopl '
. 'OR '
. 'text LIKE :text '
. 'OR '
. 'country_nopl LIKE :country_nopl '
. 'OR '
. 'country LIKE :country '
. 'OR '
. 'city_nopl LIKE :city_nopl '
. 'OR '
. 'city LIKE :city '
. ') ';
if ( is_array( $values['countries'] ) and count( $values['countries'] ) == 1 and $values['countries'][0] == 75 )
@@ -616,7 +641,12 @@ class GlobelusAdverts
':firm_name_profile_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%',
':text_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%',
':country_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%',
'city_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%'
':city_nopl' => '%' . \S::seo( $values['keyword'], true ) . '%',
':title' => '%' . trim( (string)$values['keyword'] ) . '%',
':firm_name_profile' => '%' . trim( (string)$values['keyword'] ) . '%',
':text' => '%' . trim( (string)$values['keyword'] ) . '%',
':country' => '%' . trim( (string)$values['keyword'] ) . '%',
':city' => '%' . trim( (string)$values['keyword'] ) . '%'
] ) -> fetchAll( \PDO::FETCH_ASSOC );
}
catch ( \Throwable $t )
@@ -654,4 +684,4 @@ class GlobelusAdverts
global $mdb;
return $mdb -> select( 'globelus_adverts_categories', [ 'id', 'name' ], [ 'ORDER' => [ 'name' => 'ASC' ] ] );
}
}
}

View File

@@ -61,21 +61,21 @@ class GlobelusCron
{
global $mdb;
$results = $mdb -> query( 'SELECT id, title FROM globelus_adverts WHERE title_nopl IS NULL' ) -> fetchAll( \PDO::FETCH_ASSOC );
$results = $mdb -> query( 'SELECT id, title FROM globelus_adverts WHERE title_nopl IS NULL OR title_nopl = \'\'' ) -> fetchAll( \PDO::FETCH_ASSOC );
if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
{
$mdb -> update( 'globelus_adverts', [ 'title_nopl' => \S::seo( $row['title'], true ) ], [ 'id' => $row['id'] ] );
echo( '<p>Generuje wartość nopl - ogłoszenia.</p>' );
}
$results = $mdb -> query( 'SELECT id, firm_name_profile FROM globelus_firms_data WHERE firm_name_profile_nopl IS NULL' ) -> fetchAll( \PDO::FETCH_ASSOC );
$results = $mdb -> query( 'SELECT id, firm_name_profile FROM globelus_firms_data WHERE firm_name_profile_nopl IS NULL OR firm_name_profile_nopl = \'\'' ) -> fetchAll( \PDO::FETCH_ASSOC );
if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
{
$mdb -> update( 'globelus_firms_data', [ 'firm_name_profile_nopl' => \S::seo( $row['firm_name_profile'], true ) ], [ 'id' => $row['id'] ] );
echo( '<p>Generuje wartość nopl - firmy.</p>' );
}
$results = $mdb -> query( 'SELECT id, text FROM globelus_adverts WHERE text_nopl IS NULL' ) -> fetchAll( \PDO::FETCH_ASSOC );
$results = $mdb -> query( 'SELECT id, text FROM globelus_adverts WHERE text_nopl IS NULL OR text_nopl = \'\'' ) -> fetchAll( \PDO::FETCH_ASSOC );
if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
{
$mdb -> update( 'globelus_adverts', [ 'text_nopl' => \S::seo( $row['text'], true ) ], [ 'id' => $row['id'] ] );
@@ -89,7 +89,7 @@ class GlobelusCron
echo( '<p>Generuje wartość nopl - kraje.</p>' );
}
$results = $mdb -> query( 'SELECT id, city FROM globelus_adverts WHERE city_nopl IS NULL' ) -> fetchAll( \PDO::FETCH_ASSOC );
$results = $mdb -> query( 'SELECT id, city FROM globelus_adverts WHERE city_nopl IS NULL OR city_nopl = \'\'' ) -> fetchAll( \PDO::FETCH_ASSOC );
if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
{
$mdb -> update( 'globelus_adverts', [ 'city_nopl' => \S::seo( $row['city'], true ) ], [ 'id' => $row['id'] ] );

View File

@@ -1083,9 +1083,9 @@ class GlobelusFirms
'outside_ue' => $values['outside_ue'],
'without_driving_license' => $values['without_driving_license'],
'aplication_link' => $aplication_link ? $aplication_link : null,
'title_nopl' => '',
'city_nopl' => '',
'text_nopl' => ''
'title_nopl' => \S::seo($values['title'], true),
'city_nopl' => \S::seo($values['city'], true),
'text_nopl' => \S::seo(\S::clear_advert_text($values['text']), true)
]);
$advert_id = $mdb->id();
}
@@ -1120,9 +1120,9 @@ class GlobelusFirms
'outside_ue' => $values['outside_ue'],
'without_driving_license' => $values['without_driving_license'],
'aplication_link' => $aplication_link ? $aplication_link : null,
'title_nopl' => '',
'city_nopl' => '',
'text_nopl' => ''
'title_nopl' => \S::seo($values['title'], true),
'city_nopl' => \S::seo($values['city'], true),
'text_nopl' => \S::seo(\S::clear_advert_text($values['text']), true)
], [
'AND' => [
'user_id' => $values['user_id'],

Binary file not shown.

Binary file not shown.

Binary file not shown.