"""Employees plugin main class. Blueprint-only plugin: a read-only employee directory lookup over a separate HR database. No model (the directory is an external DB) and no AssetType. The connection helper (employee_connection) stays core infrastructure in shopdb.api, shared with search and the notifications shopfloor feed. """ import json import logging from pathlib import Path from typing import List, Dict, Optional, Type from flask import Flask, Blueprint from shopdb.plugins.base import BasePlugin, PluginMeta from .api import employees_bp from .models import DirectoryEmployee logger = logging.getLogger(__name__) class EmployeesPlugin(BasePlugin): """Employees plugin - read-only HR directory lookup.""" def __init__(self): self._manifest = self._load_manifest() def _load_manifest(self) -> Dict: """Load plugin manifest from JSON file.""" manifest_path = Path(__file__).parent / 'manifest.json' if manifest_path.exists(): with open(manifest_path, 'r') as f: return json.load(f) return {} @property def meta(self) -> PluginMeta: """Return plugin metadata.""" return PluginMeta( name=self._manifest.get('name', 'employees'), version=self._manifest.get('version', '1.0.0'), description=self._manifest.get( 'description', 'Read-only employee directory lookup' ), author=self._manifest.get('author', 'ShopDB Team'), dependencies=self._manifest.get('dependencies', []), core_version=self._manifest.get('core_version', '>=0.1.0,<1.0.0'), api_prefix=self._manifest.get('api_prefix', '/api/employees'), ) def get_blueprint(self) -> Optional[Blueprint]: """Return Flask Blueprint with API routes.""" return employees_bp def get_models(self) -> List[Type]: """Self-hosted directory table (used when directory_mode=selfhosted). External mode reads a separate DB via employee_connection instead.""" return [DirectoryEmployee] def get_config_schema(self) -> List[Dict]: """Employee directory DB connection. Host/name/user are settings the wizard can edit; the password stays in .env (emitted, not stored).""" return [ {'key': 'employee_db_host', 'label': 'Employee DB host', 'type': 'text', 'secret': False, 'default': 'localhost', 'help': 'This DB must expose an "employees" table or view with columns ' 'SSO, First_Name, Last_Name, Team, Role, Picture. ' 'See plugins/employees/README.md.'}, {'key': 'employee_db_name', 'label': 'Employee DB name', 'type': 'text', 'secret': False, 'default': 'wjf_employees'}, {'key': 'employee_db_user', 'label': 'Employee DB user', 'type': 'text', 'secret': False}, {'key': 'employee_db_password', 'label': 'Employee DB password', 'type': 'password', 'secret': True, 'envvar': 'EMPLOYEE_DB_PASSWORD', 'help': 'Stored in .env, not the database. The wizard shows the line to paste.'}, ] def init_app(self, app: Flask, db_instance) -> None: """Initialize plugin with Flask app.""" logger.info(f"Employees plugin initialized (v{self.meta.version})")