Skip to content

Commit

Permalink
Enhance configuration management and web UI integration
Browse files Browse the repository at this point in the history
- Updated the .cursorules file to provide a comprehensive overview of the backend and frontend technologies, emphasizing the use of modern C++ with CMake, DuckDB, and COW HTTP Framework, as well as Svelte 5 and SvelteKit for the frontend.
- Modified the .gitignore file to include the 'diagnosis/' directory and ensure 'service-account.json' is ignored.
- Commented out web UI subdirectory additions in CMakeLists.txt to prevent unnecessary builds during development.
- Adjusted Makefile to comment out the web build command for the release process.
- Enhanced the APIServer constructor to include a new parameter for enabling the configuration UI.
- Updated the AuthMiddleware to check for an additional 'enabled' flag in AWS secret manager settings.
- Commented out the inclusion of the embedded index HTML file in embedded_ui.cpp to streamline the embedded UI content handling.
- Removed the deprecated embedded index_html.hpp file to clean up the codebase.

These changes improve the overall structure and usability of the web UI, enhance configuration management, and streamline the build process.
  • Loading branch information
Joachim Rosskopf committed Jan 15, 2025
1 parent cc905f8 commit d347cf5
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 11,879 deletions.
209 changes: 208 additions & 1 deletion .cursorules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
You are an expert in Modern c++, CMake, DuckDB and COW HTTP Framework.
The backend is written in modern C++ and uses CMake, DuckDB and COW HTTP Framework.

Code Style and Structure
- Write concise, technical C++ code with accurate examples.
Expand All @@ -10,3 +10,210 @@ Code Style and Structure
- Use catch2 for testing.
- Use duckdb for database related tasks.
- Use COW HTTP Framework for HTTP related tasks.


-----------------------------------------------------------------------------------------


The frontend is written in Svelte 5, SvelteKit, TypeScript, and modern web development.
It is crucically important, that `npm run build` creates a single file, that can be served by the backend and compiled into the single backend executable.

Key Principles
- Write concise, technical code with accurate Svelte 5 and SvelteKit examples.
- Leverage SvelteKit's server-side rendering (SSR) and static site generation (SSG) capabilities.
- Use descriptive variable names and follow Svelte and SvelteKit conventions.
- Organize files using SvelteKit's file-based routing system.
- Check whether code existing or generated has to be migrated to Svelte 5: https://svelte.dev/docs/svelte/v5-migration-guide

Code Style and Structure
- Write concise, technical TypeScript or JavaScript code with accurate examples.
- Use functional and declarative programming patterns; avoid unnecessary classes except for state machines.
- Prefer iteration and modularization over code duplication.
- Structure files: component logic, markup, styles, helpers, types.
- Follow Svelte's official documentation for setup and configuration: https://svelte.dev/docs

Naming Conventions
- Use lowercase with hyphens for component files (e.g., `components/auth-form.svelte`).
- Use PascalCase for component names in imports and usage.
- Use camelCase for variables, functions, and props.

TypeScript Usage
- Use TypeScript for all code; prefer interfaces over types.
- Avoid enums; use const objects instead.
- Use functional components with TypeScript interfaces for props.
- Enable strict mode in TypeScript for better type safety.

Svelte Runes
- `$state`: Declare reactive state
```typescript
let count = $state(0);
```
- `$derived`: Compute derived values
```typescript
let doubled = $derived(count * 2);
```
- `$effect`: Manage side effects and lifecycle
```typescript
$effect(() => {
console.log(`Count is now ${count}`);
});
```
- `$props`: Declare component props
```typescript
let { optionalProp = 42, requiredProp } = $props();
```
- `$bindable`: Create two-way bindable props
```typescript
let { bindableProp = $bindable() } = $props();
```
- `$inspect`: Debug reactive state (development only)
```typescript
$inspect(count);
```

UI and Styling
- Use Tailwind CSS for utility-first styling approach.
- Leverage Shadcn components for pre-built, customizable UI elements.
- Import Shadcn components from `$lib/components/ui`.
- Organize Tailwind classes using the `cn()` utility from `$lib/utils`.
- Use Svelte's built-in transition and animation features.

Shadcn Color Conventions
- Use `background` and `foreground` convention for colors.
- Define CSS variables without color space function:
```css
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
```
- Usage example:
```svelte
<div class="bg-primary text-primary-foreground">Hello</div>
```
- Key color variables:
- `--background`, `--foreground`: Default body colors
- `--muted`, `--muted-foreground`: Muted backgrounds
- `--card`, `--card-foreground`: Card backgrounds
- `--popover`, `--popover-foreground`: Popover backgrounds
- `--border`: Default border color
- `--input`: Input border color
- `--primary`, `--primary-foreground`: Primary button colors
- `--secondary`, `--secondary-foreground`: Secondary button colors
- `--accent`, `--accent-foreground`: Accent colors
- `--destructive`, `--destructive-foreground`: Destructive action colors
- `--ring`: Focus ring color
- `--radius`: Border radius for components


Component Development
- Create .svelte files for Svelte components.
- Use .svelte.ts files for component logic and state machines.
- Implement proper component composition and reusability.
- Use Svelte's props for data passing.
- Leverage Svelte's reactive declarations for local state management.

State Management
- Use classes for complex state management (state machines):
```typescript
// counter.svelte.ts
class Counter {
count = $state(0);
incrementor = $state(1);

increment() {
this.count += this.incrementor;
}

resetCount() {
this.count = 0;
}

resetIncrementor() {
this.incrementor = 1;
}
}

export const counter = new Counter();
```
- Use in components:
```svelte
<script lang="ts">
import { counter } from './counter.svelte.ts';
</script>

<button on:click={() => counter.increment()}>
Count: {counter.count}
</button>
```

Routing and Pages
- Ensure that the routing is compatible with compilation to a single file.

Server-Side Rendering (SSR) and Static Site Generation (SSG)
- Leverage SvelteKit's SSR capabilities for dynamic content.
- Implement SSG for static pages using prerender option.
- Use the adapter-auto for automatic deployment configuration.

Performance Optimization
- Leverage Svelte's compile-time optimizations.
- Use `{#key}` blocks to force re-rendering of components when needed.
- Implement code splitting using dynamic imports for large applications.
- Profile and monitor performance using browser developer tools.
- Use `$effect.tracking()` to optimize effect dependencies.
- Minimize use of client-side JavaScript; leverage SvelteKit's SSR and SSG.
- Implement proper lazy loading for images and other assets.

Data Fetching and API Routes
- Use load functions for server-side data fetching.
- Implement proper error handling for data fetching operations.
- Create API routes in the src/routes/api/ directory.
- Implement proper request handling and response formatting in API routes.
- Use SvelteKit's hooks for global API middleware.

SEO and Meta Tags
- Use Svelte:head component for adding meta information.
- Implement canonical URLs for proper SEO.
- Create reusable SEO components for consistent meta tag management.

Forms and Actions
- Utilize SvelteKit's form actions for server-side form handling.
- Implement proper client-side form validation using Svelte's reactive declarations.
- Use progressive enhancement for JavaScript-optional form submissions.

Internationalization (i18n) with Paraglide.js
- Use Paraglide.js for internationalization: https://inlang.com/m/gerre34r/library-inlang-paraglideJs
- Install Paraglide.js: `npm install @inlang/paraglide-js`
- Set up language files in the `languages` directory.
- Use the `t` function to translate strings:
```svelte
<script>
import { t } from '@inlang/paraglide-js';
</script>

<h1>{t('welcome_message')}</h1>
```
- Support multiple languages and RTL layouts.
- Ensure text scaling and font adjustments for accessibility.

Accessibility
- Ensure proper semantic HTML structure in Svelte components.
- Implement ARIA attributes where necessary.
- Ensure keyboard navigation support for interactive elements.
- Use Svelte's bind:this for managing focus programmatically.

Key Conventions
1. Embrace Svelte's simplicity and avoid over-engineering solutions.
2. Use SvelteKit for full-stack applications with SSR and API routes.
3. Prioritize Web Vitals (LCP, FID, CLS) for performance optimization.
4. Use environment variables for configuration management.
5. Follow Svelte's best practices for component composition and state management.
6. Ensure cross-browser compatibility by testing on multiple platforms.
7. Keep your Svelte and SvelteKit versions up to date.

Documentation
- Svelte 5 Runes: https://svelte-5-preview.vercel.app/docs/runes
- Svelte Documentation: https://svelte.dev/docs
- SvelteKit Documentation: https://kit.svelte.dev/docs
- Paraglide.js Documentation: https://inlang.com/m/gerre34r/library-inlang-paraglideJs/usage

Refer to Svelte, SvelteKit, and Paraglide.js documentation for detailed information on components, internationalization, and best practices.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ test/python/__pycache__/
vcpkg_installed/
*.db
*.db.wal
service-account.json
service-account.json
diagnosis/
16 changes: 8 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ include_directories(
)

# Add web UI
message(STATUS "Adding web UI subdirectory...")
add_subdirectory(web)
message(STATUS "Web UI subdirectory added")
# message(STATUS "Adding web UI subdirectory...")
# add_subdirectory(web)
# message(STATUS "Web UI subdirectory added")

# Create flapi-lib
add_library(flapi-lib STATIC
Expand All @@ -181,12 +181,12 @@ add_library(flapi-lib STATIC
)

# Ensure web_ui is built before flapi-lib
message(STATUS "Setting up web UI dependencies...")
add_dependencies(flapi-lib web_ui)
#message(STATUS "Setting up web UI dependencies...")
#add_dependencies(flapi-lib web_ui)

# Link against web_ui to get its include directories
target_link_libraries(flapi-lib PUBLIC web_ui_lib)
message(STATUS "Web UI dependencies configured")
#target_link_libraries(flapi-lib PUBLIC web_ui_lib)
#message(STATUS "Web UI dependencies configured")

# Link libraries to flapi-lib
target_link_libraries(flapi-lib PUBLIC
Expand Down Expand Up @@ -254,7 +254,7 @@ if(WIN32)
endif()

# Add dependency on web UI
add_dependencies(flapi-lib web_ui)
#add_dependencies(flapi-lib web_ui)

# Include embedded UI headers
target_include_directories(flapi-lib PRIVATE ${CMAKE_SOURCE_DIR}/src/include)
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ else
release:
@echo "Building release version $(if $(CROSS_COMPILE),for $(CROSS_COMPILE),native)..."
@mkdir -p $(RELEASE_DIR)
@$(MAKE) web
# @$(MAKE) web
@cd $(RELEASE_DIR) && $(CMAKE) -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF \
$(CMAKE_GENERATOR) $(CMAKE_EXTRA_FLAGS) ../..
@$(CMAKE) --build $(RELEASE_DIR) --config Release
Expand Down
2 changes: 1 addition & 1 deletion src/api_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace flapi {

APIServer::APIServer(std::shared_ptr<ConfigManager> cm, std::shared_ptr<DatabaseManager> db_manager)
APIServer::APIServer(std::shared_ptr<ConfigManager> cm, std::shared_ptr<DatabaseManager> db_manager, bool enable_config_ui)
: configManager(cm), dbManager(db_manager), openAPIDocGenerator(std::make_shared<OpenAPIDocGenerator>(cm, db_manager)), requestHandler(dbManager, cm)
{
createApp();
Expand Down
3 changes: 1 addition & 2 deletions src/auth_middleware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ std::optional<AwsAuthParams> AwsHelper::tryGetS3AuthParams(const std::string& se
}

// ------------------------------------------------------------------------------------------------

void AuthMiddleware::initialize(std::shared_ptr<ConfigManager> config_manager) {
this->config_manager = config_manager;
this->db_manager = DatabaseManager::getInstance();
Expand All @@ -108,7 +107,7 @@ void AuthMiddleware::initialize(std::shared_ptr<ConfigManager> config_manager) {

void AuthMiddleware::initializeAwsSecretsManager() {
for (const auto& endpoint : config_manager->getEndpoints()) {
if (!endpoint.auth.from_aws_secretmanager) {
if (!endpoint.auth.from_aws_secretmanager || !endpoint.auth.enabled) {
continue;
}

Expand Down
5 changes: 3 additions & 2 deletions src/embedded_ui.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#include "embedded_ui.hpp"
#include "embedded/index_html.hpp"
//#include "embedded/index_html.hpp"

namespace flapi {
namespace embedded_ui {

std::string_view get_file_content(const std::string& path) {
// Since we're using a single file approach, all paths return the same content
return std::string_view(reinterpret_cast<const char*>(index_html), index_html_len);
//return std::string_view(reinterpret_cast<const char*>(index_html), index_html_len);
return std::string_view("");
}

} // namespace embedded_ui
Expand Down
2 changes: 1 addition & 1 deletion src/include/api_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class HeartbeatWorker; // forward declaration
class APIServer
{
public:
explicit APIServer(std::shared_ptr<ConfigManager> config_manager, std::shared_ptr<DatabaseManager> db_manager);
explicit APIServer(std::shared_ptr<ConfigManager> config_manager, std::shared_ptr<DatabaseManager> db_manager, bool enable_config_ui);
~APIServer();

crow::response getConfig();
Expand Down
Loading

0 comments on commit d347cf5

Please sign in to comment.