feat(Production): Complete production deployment infrastructure

- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
This commit is contained in:
2025-10-25 19:18:37 +02:00
parent caa85db796
commit fc3d7e6357
83016 changed files with 378904 additions and 20919 deletions

View File

@@ -0,0 +1,148 @@
<div class="counter-component" data-poll-interval="{pollInterval}">
<div class="counter-display">
<h2>Counter: <span class="count">{count}</span></h2>
<if condition="lastUpdate">
<p class="last-update">Last update: {lastUpdate}</p>
</if>
</div>
<div class="counter-actions">
<button
data-live-action="decrement"
data-live-prevent
class="btn btn-danger"
>
- Decrement
</button>
<button
data-live-action="increment"
data-live-prevent
class="btn btn-success"
>
+ Increment
</button>
<button
data-live-action="reset"
data-live-prevent
class="btn btn-secondary"
>
Reset
</button>
</div>
<div class="counter-custom">
<form data-live-action="addAmount" data-live-prevent>
<input
type="number"
name="amount"
placeholder="Enter amount"
value="5"
class="form-control"
/>
<button type="submit" class="btn btn-primary">Add Amount</button>
</form>
</div>
</div>
<style>
.counter-component {
max-width: 500px;
margin: 2rem auto;
padding: 2rem;
border: 2px solid #ddd;
border-radius: 8px;
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.counter-display {
text-align: center;
margin-bottom: 2rem;
}
.counter-display h2 {
font-size: 2rem;
margin: 0 0 0.5rem 0;
color: #333;
}
.counter-display .count {
color: #007bff;
font-weight: bold;
}
.last-update {
font-size: 0.875rem;
color: #666;
margin: 0;
}
.counter-actions {
display: flex;
gap: 0.5rem;
margin-bottom: 1.5rem;
}
.counter-actions button {
flex: 1;
}
.counter-custom {
padding-top: 1rem;
border-top: 1px solid #eee;
}
.counter-custom form {
display: flex;
gap: 0.5rem;
}
.counter-custom input {
flex: 1;
}
/* Button Styles */
.btn {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.875rem;
font-weight: 500;
transition: all 0.2s;
}
.btn:hover {
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.btn-success {
background: #28a745;
color: white;
}
.btn-danger {
background: #dc3545;
color: white;
}
.btn-secondary {
background: #6c757d;
color: white;
}
.btn-primary {
background: #007bff;
color: white;
}
.form-control {
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 0.875rem;
}
</style>

View File

@@ -0,0 +1,153 @@
<div class="notification-bell" data-poll-interval="{pollInterval}">
<button class="bell-icon" type="button">
=
<if condition="count > 0">
<span class="badge">{count}</span>
</if>
</button>
<div class="notification-dropdown" style="display: none;">
<div class="notification-header">
<h3>Notifications</h3>
<if condition="count > 0">
<button
data-live-action="markAllAsRead"
data-live-prevent
class="mark-all-read"
>
Mark all as read
</button>
</if>
</div>
<div class="notification-list">
<if condition="count > 0">
<for items="notifications" as="notification">
<div class="notification-item">
<p>{notification.message}</p>
<button
data-live-action="markAsRead"
data-param-id="{notification.id}"
data-live-prevent
class="mark-read-btn"
>

</button>
</div>
</for>
</if>
<if condition="count == 0">
<div class="no-notifications">
<p>No new notifications</p>
</div>
</if>
</div>
</div>
</div>
<style>
.notification-bell {
position: relative;
display: inline-block;
}
.bell-icon {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
position: relative;
}
.badge {
position: absolute;
top: -5px;
right: -5px;
background: #ff4444;
color: white;
border-radius: 50%;
padding: 2px 6px;
font-size: 0.75rem;
}
.notification-dropdown {
position: absolute;
top: 100%;
right: 0;
background: white;
border: 1px solid #ddd;
border-radius: 4px;
width: 300px;
max-height: 400px;
overflow-y: auto;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
z-index: 1000;
}
.notification-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
border-bottom: 1px solid #eee;
}
.notification-header h3 {
margin: 0;
font-size: 1rem;
}
.mark-all-read {
background: none;
border: none;
color: #007bff;
cursor: pointer;
font-size: 0.875rem;
}
.notification-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem 1rem;
border-bottom: 1px solid #eee;
}
.notification-item p {
margin: 0;
flex: 1;
font-size: 0.875rem;
}
.mark-read-btn {
background: none;
border: none;
color: #28a745;
cursor: pointer;
font-size: 1.2rem;
}
.no-notifications {
padding: 2rem;
text-align: center;
color: #999;
}
</style>
<script>
// Toggle dropdown on click
document.querySelector('[data-live-component="{componentId}"] .bell-icon').addEventListener('click', function() {
const dropdown = this.nextElementSibling;
dropdown.style.display = dropdown.style.display === 'none' ? 'block' : 'none';
});
// Close dropdown when clicking outside
document.addEventListener('click', function(e) {
const bell = document.querySelector('[data-live-component="{componentId}"]');
if (bell && !bell.contains(e.target)) {
const dropdown = bell.querySelector('.notification-dropdown');
if (dropdown) dropdown.style.display = 'none';
}
});
</script>