bayan-api / docs /architecture /02-class-diagram.md
youssefreda9's picture
HF Deploy: Fix syntax error with smart quotes in popup.js
fe1e225
|
Raw
History Blame Contribute Delete
8.7 kB

02 — UML Class Diagram

Overview

This diagram models the complete class structure of the BAYAN system across Frontend and Backend layers, showing composition, aggregation, inheritance, and dependency relationships.

Class Diagram

classDiagram
    direction TB

    %% ─── Frontend: Editor Core ───
    class Editor {
        -analyzeTimeout: Timer
        -analyzeAbortController: AbortController
        -undoStack: Array
        -redoStack: Array
        -dismissedWords: Set
        +initEditor()
        +getEditorText(): string
        +setEditorHTML(html)
        +updateEditorStats()
        +analyzeTextDelayed()
        +applyCorrection()
        +dismissSuggestion(suggestion)
        +applyAllSuggestions()
        +pushUndoState()
        +editorUndo(): boolean
        +editorRedo(): boolean
        +clearEditor()
        +copyText()
    }

    class Renderer {
        +renderCorrections(text, suggestions)
        +highlightErrors(editor, suggestions)
        +createErrorSpan(text, type, id)
        +escapeHtml(text): string
        +renderSuggestionsList(suggestions)
        +renderSuggestionCard(suggestion, idx)
    }

    class SelectionManager {
        +saveSelection(): Range
        +restoreSelection(range)
        +getCaretOffset(): number
        +setCaretOffset(offset)
        +getSelectedText(): string
    }

    class FormatManager {
        +execFormat(command, value)
        +toggleBold()
        +toggleItalic()
        +toggleUnderline()
        +setFontFamily(font)
        +setFontSize(size)
        +setTextColor(color)
        +setHighlightColor(color)
        +setAlignment(align)
        +insertList(type)
        +clearFormatting()
        +initDocSearch()
    }

    %% ─── Frontend: Auth ───
    class AuthManager {
        +signInAsGuest(): Promise
        +signInWithGoogle(): Promise
        +linkGoogle(): Promise
        +signOut(): Promise
        +getDisplayName(user): string
        +getAuthProvider(user): string
        +getAvatarUrl(user): string
        +isGuestUser(user): boolean
    }

    class AuthUI {
        +bindAuthUIEvents()
        +showAuthGate()
        +hideAuthGate()
        +updateAuthUI(user)
        +closeAuthMenu()
        +showAuthOfflineBanner(show)
    }

    class SessionManager {
        +initSession()
        +onAuthStateChange(callback)
        +getSession(): Session
        +refreshSession()
    }

    class SupabaseClient {
        +getSupabaseClient(): Client
        -url: string
        -anonKey: string
    }

    %% ─── Frontend: Documents ───
    class DocumentManager {
        +createDocument(title, content): Promise
        +loadDocuments(): Promise
        +loadDocument(id): Promise
        +saveDocument(id, content): Promise
        +renameDocument(id, title): Promise
        +deleteDocument(id): Promise
    }

    class DocumentUI {
        -docState: DocState
        +setDocState(state)
        +getDocState(): DocState
        +renderDocList(docs)
        +openDocument(id)
        +updateTitleBar()
        +loadAndRenderList()
    }

    class DocState {
        +currentDocumentId: string
        +currentDocumentTitle: string
        +hasUnsavedChanges: boolean
    }

    %% ─── Frontend: Summaries ───
    class SummaryManager {
        +createSummary(docId, originalText, summaryText): Promise
        +loadSummaries(docId): Promise
        +deleteSummary(id): Promise
    }

    class SummaryUI {
        +renderSummaryList(summaries)
        +showSummaryPanel(summary)
        +exportSummaryAsTxt()
    }

    %% ─── Frontend: Settings ───
    class SettingsAPI {
        +loadSettings(): Promise
        +saveSettings(settings): Promise
    }

    class SettingsSync {
        +initSettingsSync()
        +applySettings(settings)
        +getLocalSettings(): object
    }

    %% ─── Frontend: Sync ───
    class SyncManager {
        -syncInterval: Timer
        -isOnline: boolean
        +initSync()
        +scheduleSave()
        +syncNow(): Promise
        +handleOnline()
        +handleOffline()
    }

    class SyncQueue {
        -queue: Array
        +enqueue(operation)
        +dequeue(): Operation
        +peek(): Operation
        +isEmpty(): boolean
        +flush(): Promise
    }

    class SyncResolver {
        +resolve(local, remote): Resolved
        +mergeConflict(a, b): string
        +lastWriteWins(a, b): object
    }

    %% ─── Frontend: UI ───
    class UIManager {
        +showPage(pageId)
        +switchTab(tabId)
        +showToast(message, type)
        +setAnalyzingState(isAnalyzing)
        +updateSuggestionCounts(s, g, p)
        +updateWritingScore(s, g, p)
        +renderSuggestionsList(suggestions)
    }

    class ThemeManager {
        +initTheme()
        +toggleTheme()
        +getPreferredTheme(): string
        +applyTheme(theme)
    }

    class APIClient {
        +apiPost(endpoint, body): Promise
        +apiGet(endpoint): Promise
        -baseUrl: string
    }

    %% ─── Backend: Flask ───
    class FlaskApp {
        +index(): Response
        +health_check(): JSON
        +debug_models(): JSON
        +analyze_text(): JSON
        +spelling_correction(): JSON
        +grammar_correction(): JSON
        +add_punctuation(): JSON
        +summarize(): JSON
        +autocomplete(): JSON
    }

    class ModelLoader {
        +load_models()
        +ensure_models_loaded()
        -summarization_model: SummarizationModel
        -spelling_model: SpellingModel
        -grammar_model: GrammarModel
        -punctuation_model: PunctuationModel
        -autocomplete_model: AutocompleteModel
    }

    %% ─── Backend: NLP Services ───
    class AraSpellService {
        +correct(text): CorrectionResult
        +get_alternatives(word): List
        -model: EncoderDecoderModel
        -tokenizer: AutoTokenizer
    }

    class GrammarService {
        +check(text): List~GrammarError~
        +suggest_fix(error): string
        -rules: GrammarRules
    }

    class PunctuationService {
        +restore(text): string
        -model: PunctuationModel
    }

    class AutoCompleteService {
        +complete(prefix): List~Suggestion~
        -model: LanguageModel
    }

    class SummarizationService {
        +summarize(text, max_length): string
        -model: MBartForConditionalGeneration
        -tokenizer: AutoTokenizer
    }

    class HFInference {
        +hf_summarize(text): string
        +hf_correct_spelling(text): string
        +hf_add_punctuation(text): string
        +hf_autocomplete(text): string
        +check_hf_api_available(): boolean
    }

    %% ─── Relationships ───
    Editor *-- SelectionManager : uses
    Editor *-- Renderer : renders via
    Editor o-- FormatManager : formatting
    Editor --> APIClient : sends text
    Editor --> SyncManager : triggers save

    AuthManager --> SupabaseClient : authenticates via
    AuthManager --> SessionManager : manages session
    AuthUI --> AuthManager : calls

    DocumentManager --> SupabaseClient : CRUD
    DocumentUI --> DocumentManager : delegates to
    DocumentUI *-- DocState : owns

    SummaryManager --> SupabaseClient : CRUD
    SummaryUI --> SummaryManager : delegates to

    SettingsSync --> SettingsAPI : persists via
    SettingsAPI --> SupabaseClient : CRUD

    SyncManager *-- SyncQueue : owns
    SyncManager *-- SyncResolver : resolves with
    SyncManager --> DocumentManager : saves via

    UIManager --> Editor : controls
    UIManager --> Renderer : renders

    FlaskApp *-- ModelLoader : loads models
    FlaskApp --> AraSpellService : spelling
    FlaskApp --> GrammarService : grammar
    FlaskApp --> PunctuationService : punctuation
    FlaskApp --> AutoCompleteService : autocomplete
    FlaskApp --> SummarizationService : summarization
    FlaskApp --> HFInference : remote fallback

    ModelLoader --> AraSpellService : initializes
    ModelLoader --> GrammarService : initializes
    ModelLoader --> PunctuationService : initializes
    ModelLoader --> AutoCompleteService : initializes
    ModelLoader --> SummarizationService : initializes

Design Rationale

  • Composition (*--): Editor owns SelectionManager and Renderer — they cannot exist without the Editor.
  • Aggregation (o--): FormatManager is reusable and independent.
  • Dependency (-->): API calls and data flows between modules.
  • Frontend modules are globally-scoped functions (vanilla JS) but modeled as classes for UML clarity.
  • Backend uses Flask route functions modeled as FlaskApp methods, with NLP services as separate classes.