Personal Finances Application — zarządca finansów w C++
Wieloużytkownikowa aplikacja konsolowa napisana w C++ do śledzenia przychodów i wydatków. Pełny system logowania z rate limitingiem (3 próby hasła), persystencja danych przez pliki XML, walidacja dat z obsługą roku przestępnego, bilansy za bieżący miesiąc, poprzedni miesiąc lub dowolny okres — wszystko w obiektowej architekturze z dziedziczeniem i oddzielonymi warstwami.
01Wygląd aplikacji — terminal
Aplikacja działa w trybie konsolowym — czyste menu tekstowe, nawigacja przez pojedynczy znak wpisany z klawiatury, każde działanie daje informację zwrotną w terminalu. Dwa menu: główne (dla niezalogowanych) i użytkownika (po zalogowaniu).
Menu główne i logowanie
ekran logowania — rate limiter odlicza pozostałe próby przy każdej błędnej
Menu użytkownika
menu użytkownika — 7 opcji, pętla while(true) do wylogowania
Dodawanie przychodu
dodawanie przychodu — wybór daty (dziś / inna), opis, kwota z walidacją
Dodawanie wydatku z własną datą
wydatek z własną datą — walidacja kwoty (tylko cyfry), pętla do momentu poprawnego wpisu
Bilans bieżącego miesiąca
bilans bieżącego miesiąca — lista operacji posortowana chronologicznie + sumy + wynik
Bilans za dowolny okres
bilans za dowolny okres — zakres dat wpisywany ręcznie, walidacja formatu i zakresu
Rejestracja nowego użytkownika
rejestracja — login sprawdzany pod kątem unikalności, dane zapisywane do users.xml
02Funkcjonalności
Wielu użytkowników
Rejestracja z weryfikacją unikalności loginu. Logowanie z 3 próbami hasła (rate limit). Zmiana hasła. Dane w users.xml.
Przychody i wydatki
Dodawanie z datą dzisiejszą lub własną. Walidacja kwoty (tylko cyfry, pętla do momentu poprawnego wpisu). Opis pozycji.
Trzy tryby bilansu
Bieżący miesiąc, poprzedni miesiąc (z obsługą przełomu roku) i dowolny okres. Operacje posortowane chronologicznie, sumy, wynik.
Walidacja dat
Format YYYY-MM-DD, zakres 2000–dziś, poprawność dnia w miesiącu z obsługą roku przestępnego (luty 28/29).
Persystencja XML
Dane w trzech plikach XML przez bibliotekę CMarkup. Odczyt przy starcie, zapis przy każdej operacji. Izolacja danych per userId.
Architektura OOP
9 klas z jasną odpowiedzialnością. Dziedziczenie XmlFile→UsersFile/FinancesFile. Wskaźnik do FinanceManager tworzony po zalogowaniu.
03Architektura — klasy i dziedziczenie
04Persystencja danych — XML
Dane przechowywane w trzech plikach XML przez bibliotekę CMarkup. Daty jako liczby całkowite (YYYYMMDD) — porównanie zakresów to zwykłe >= i <=.
<!-- incomes.xml — przykładowy rekord -->
<INCOMES>
<INCOME>
<incomeId>1</incomeId>
<userId>1</userId>
<date>20241101</date> <!-- int YYYYMMDD → proste porównanie -->
<item>Wyplata listopad</item>
<amount>5800.000000</amount>
</INCOME>
</INCOMES>
05Logika dat i sortowanie
// Rok przestępny — własna implementacja, bez zewnętrznych bibliotek
int DatesSupportingMethods::howManyDays(int year, int month) {
const int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int result = days[month - 1];
if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
result = 29; // luty w roku przestępnym
return result;
}
// std::sort z komparatorem zdefiniowanym jako statyczna metoda klasy
std::sort(input.begin(), input.end(), Operation::compareByDate);
// Porównanie dat to porównanie intów — daty przechowywane jako YYYYMMDD
if ((dateToCompare >= comparisonStart) && (dateToCompare <= comparisonEnd)) {
operations.push_back(operation);
}
06Czego dowodzi ten projekt
C++ OOP
Klasy, dziedziczenie, enkapsulacja, konstruktory z inicjalizatorami, wskaźnik tworzony dynamicznie po zalogowaniu.
Separation of concerns
Każda klasa ma jedną odpowiedzialność — UserManager nie wie nic o XML, FinancesFile nie wie nic o interfejsie.
STL w praktyce
std::vector<Operation>, std::sort z komparatorem, std::stringstream, range-for.
Własna logika daty
Rok przestępny, poprzedni miesiąc z przełomem roku, walidacja formatu i zakresu — bez bibliotek zewnętrznych.
Persystencja plików
Odczyt XML przy starcie, zapis przy każdej zmianie, izolacja danych per userId, obsługa błędów.
Punkt startowy
Ten projekt poprzedza całe portfolio webowe. Ewolucja: od C++ i XML do Python/FastAPI/pgvector i OpenAI.
Zobacz kod na GitHubie
Pełny kod C++ — ~7400 linii rozłożonych na 9 klas w osobnych plikach .h/.cpp.
Zobacz kod na GitHub