#!/usr/bin/env python3 """ Project Starlight Document Management System Manages revision control for mission documentation and procedures """ import json import datetime import hashlib import re from typing import Dict, List, Optional, Any from dataclasses import dataclass @dataclass class DocumentVersion: """Document version information""" version: str author: str date: str changes: str classification: str document_type: str checksum: str class DocumentManager: """Main document management class for Project Starlight""" def __init__(self): self.documents = {} self.approval_matrix = { "CRITICAL": ["Mission Director"], "MAJOR": ["Operations Manager", "Mission Director"], "MINOR": ["Department Head", "Operations Manager"], "PATCH": ["Document Owner"] } def generate_document_id(self, doc_type: str, classification: str, version: str) -> str: """Generate standardized document ID""" return f"{doc_type}-{classification}-{version}" def parse_version(self, version: str) -> Dict[str, int]: """Parse semantic version string""" match = re.match(r'(\d+)\.(\d+)\.(\d+)', version) if match: return { "major": int(match.group(1)), "minor": int(match.group(2)), "patch": int(match.group(3)) } return {"major": 0, "minor": 0, "patch": 0} def increment_version(self, current_version: str, change_type: str) -> str: """Increment version based on change type""" version_dict = self.parse_version(current_version) if change_type == "CRITICAL": version_dict["major"] += 1 version_dict["minor"] = 0 version_dict["patch"] = 0 elif change_type == "MAJOR": version_dict["minor"] += 1 version_dict["patch"] = 0 elif change_type == "MINOR": version_dict["patch"] += 1 elif change_type == "PATCH": version_dict["patch"] += 1 return f"{version_dict['major']}.{version_dict['minor']}.{version_dict['patch']}" def create_change_request(self, document_id: str, requester: str, change_type: str, description: str, impact_assessment: str) -> Dict[str, Any]: """Create a structured change request""" today = datetime.datetime.now().strftime("%Y%m%d") sequence = len([doc for doc in self.documents.values() if today in doc["date"]]) + 1 change_request = { "id": f"CR-{today}-{sequence:03d}", "document_id": document_id, "requester": requester, "date": datetime.datetime.now().isoformat(), "change_type": change_type, "description": description, "impact_assessment": impact_assessment, "approval_required": self.approval_matrix.get(change_type, ["Document Owner"]), "status": "PENDING", "implementation_date": None } return change_request def document_checksum(self, content: str) -> str: """Generate SHA-256 checksum of document content""" return hashlib.sha256(content.encode('utf-8')).hexdigest() def register_document(self, doc_type: str, classification: str, version: str, title: str, author: str, content: str, changes: str = "Initial version") -> str: """Register a new document in the system""" document_id = self.generate_document_id(doc_type, classification, version) checksum = self.document_checksum(content) document_info = { "id": document_id, "title": title, "doc_type": doc_type, "classification": classification, "version": version, "author": author, "date": datetime.datetime.now().isoformat(), "content": content, "changes": changes, "checksum": checksum, "status": "ACTIVE", "history": [] } self.documents[document_id] = document_info return document_id def update_document(self, document_id: str, new_content: str, author: str, change_type: str, changes_description: str) -> Optional[str]: """Update an existing document with new version""" if document_id not in self.documents: return None doc = self.documents[document_id] # Archive current version version_info = { "version": doc["version"], "author": doc["author"], "date": doc["date"], "changes": doc["changes"], "checksum": doc["checksum"] } doc["history"].append(version_info) # Generate new version new_version = self.increment_version(doc["version"], change_type) # Update document doc["version"] = new_version doc["author"] = author doc["date"] = datetime.datetime.now().isoformat() doc["content"] = new_content doc["changes"] = changes_description doc["checksum"] = self.document_checksum(new_content) # Generate new document ID new_document_id = self.generate_document_id(doc["doc_type"], doc["classification"], new_version) self.documents[new_document_id] = doc del self.documents[document_id] return new_document_id def get_document_history(self, document_id: str) -> List[Dict[str, str]]: """Get version history for a document""" # Find current version by pattern matching current_doc = None doc_pattern = re.sub(r'\d+\.\d+\.\d+$', '.*', document_id) for doc_id, doc in self.documents.items(): if re.match(doc_pattern.replace('*', '\*'), doc_id): current_doc = doc break if current_doc: return current_doc["history"] return [] def generate_distribution_list(self, document_id: str, change_type: str) -> List[str]: """Generate distribution list based on document type and change type""" base_distribution = [ "mission-director@starlight.project", "operations-lead@starlight.project", "security-team@starlight.project" ] # Add specialized lists based on document type if "SCAN" in document_id: base_distribution.extend([ "detection-team@starlight.project", "model-specialists@starlight.project" ]) elif "TRN" in document_id: base_distribution.extend([ "crew-personnel@starlight.project", "ground-operations@starlight.project", "training-coordinators@starlight.project" ]) elif "SEC" in document_id: base_distribution.extend([ "security-officers@starlight.project", "incident-response@starlight.project" ]) # Add urgent distribution for critical changes if change_type == "CRITICAL": base_distribution.extend([ "emergency-responders@starlight.project", "executive-team@starlight.project" ]) return list(set(base_distribution)) # Remove duplicates def export_document_registry(self) -> Dict[str, Any]: """Export complete document registry for backup""" registry = { "export_date": datetime.datetime.now().isoformat(), "total_documents": len(self.documents), "documents": {} } for doc_id, doc_info in self.documents.items(): # Exclude content from registry export for security registry["documents"][doc_id] = { "title": doc_info["title"], "doc_type": doc_info["doc_type"], "classification": doc_info["classification"], "version": doc_info["version"], "author": doc_info["author"], "date": doc_info["date"], "status": doc_info["status"], "checksum": doc_info["checksum"], "history_count": len(doc_info["history"]) } return registry def main(): """Example usage of Document Management System""" dm = DocumentManager() # Example: Register mission checklist checklist_content = """ # Mission Checklists v1.0 ## Pre-Mission Procedures - [ ] Verify detection systems operational - [ ] Confirm model accuracy >95% - [ ] Check blockchain connectivity """ doc_id = dm.register_document( doc_type="CHK", classification="1", version="1.0.0", title="Mission Pre-Launch Checklist", author="Mission Director", content=checklist_content, changes="Initial version" ) print(f"Registered document: {doc_id}") # Example: Create change request change_req = dm.create_change_request( document_id=doc_id, requester="Operations Manager", change_type="MINOR", description="Add blockchain verification step", impact_assessment="Adds 5 minutes to pre-mission checklist" ) print(f"Change request created: {change_req['id']}") # Example: Update document updated_content = checklist_content + "- [ ] Verify blockchain transaction integrity\n" new_doc_id = dm.update_document( document_id=doc_id, new_content=updated_content, author="Operations Manager", change_type="MINOR", changes_description="Added blockchain verification step" ) print(f"Document updated to: {new_doc_id}") # Example: Generate distribution list if new_doc_id: distribution = dm.generate_distribution_list(new_doc_id, "MINOR") print(f"Distribution list: {len(distribution)} recipients") else: print("Document update failed") # Export registry registry = dm.export_document_registry() print(f"Registry exported with {registry['total_documents']} documents") if __name__ == "__main__": main()