- More than 20 years experience
- Complete assessments
- No agency fees
Error executing template "Designs/ClientBase_generated/Paragraph/JumbotronContainer.cshtml" System.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK__ItemType__3214EC07EAC40CA3'. Cannot insert duplicate key in object 'dbo.ItemType_JumbotronConfiguration'. The duplicate key value is (162955). The statement has been terminated. at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount) at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount) at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping) at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping) at System.Data.Common.DbDataAdapter.Update(DataSet dataSet, String srcTable) at Dynamicweb.Content.Items.Queries.Repository.Update(IEnumerable`1 items, ItemContext context, Boolean synchronizePages) at Dynamicweb.Content.Items.Queries.Repository.Update(ItemEntry item, ItemContext context) at Dynamicweb.Content.Items.ItemEntry.Save(ItemContext context) at Bluedesk.DynamicWeb.ItemTypes.Configuration.JumbotronConfiguration.GetJumbotronStylesheet() at CompiledRazorTemplates.Dynamic.RazorEngine_9813934ec80c41e7861fbbfcffa48a4d.Execute() in D:\dynamicweb.net\Solutions\Bluedesk\worldemp.cloud.dynamicweb-cms.com\files\Templates\Designs\ClientBase_generated\Paragraph\JumbotronContainer.cshtml:line 276 at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate() ClientConnectionId:3225aab4-26ae-4fd5-92e4-f3ad397326c2 Error Number:2627,State:1,Class:14
1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 @using Dynamicweb; 3 @using Dynamicweb.Content.Items; 4 @using Dynamicweb.Content.Items.Metadata; 5 @using Bluedesk.DynamicWeb.ItemTypes; 6 @using Bluedesk.DynamicWeb.ItemTypes.Settings; 7 8 9 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 10 @using Dynamicweb; 11 @using Dynamicweb.Content.Items; 12 @using Bluedesk.DynamicWeb.ItemTypes; 13 @using Bluedesk.DynamicWeb.ItemTypes.Extensions; 14 @using Bluedesk.DynamicWeb.ItemTypes.Configuration; 15 @using Bluedesk.DynamicWeb.ItemTypes.Settings.Configuration; 16 @using Dynamicweb; 17 @using Dynamicweb.Frontend 18 @using Bluedesk.DynamicWeb.ItemTypes.BaseSolution; 19 20 @helper RenderButton(CTAButton button, PageView Pageview) 21 { 22 23 if (!string.IsNullOrWhiteSpace(button.GetLink(Pageview))) 24 { 25 string Template = button.GetButtonTemplate().Replace("{{ ButtonLink }}", button.GetLink(Pageview)); 26 @Template; 27 } 28 } 29 30 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 31 @using Dynamicweb; 32 @using Dynamicweb.Content.Items; 33 @using Bluedesk.DynamicWeb.ItemTypes; 34 35 @functions { 36 37 Dictionary<string, string> GetFontConfiguration(string TextColor, FontConfigurationItemTab FontConfiguration) 38 { 39 var colorService = new ColorSwatchService(); 40 TextColor = !string.IsNullOrWhiteSpace(TextColor) ? TextColor : "" ; 41 TextColor = !TextColor.Contains("#") ? colorService.GetHexColor(Pageview.AreaID, TextColor) : TextColor; 42 Dictionary<string, string> FontConfig = new Dictionary<string, string>() { 43 { "textColor" , TextColor }, 44 { "fontSize" , FontConfiguration.FontSize }, 45 { "lineHeight", FontConfiguration.LineHeight}, 46 { "fontFamily" , FontConfiguration.FontConfiguration.FontFamily }, 47 { "fontWeight" , FontConfiguration.FontWeight }, 48 { "fontStyle" , FontConfiguration.FontStyle } 49 }; 50 return FontConfig; 51 } 52 53 public string GenerateButtonConfigVariables(ButtonConfiguration BC, MasterConfig mc, int areaId) 54 { 55 string ButtonLabelAlignment = BC.ButtonLabelAlignment; 56 switch (ButtonLabelAlignment) 57 { 58 case "align-left": 59 ButtonLabelAlignment = "flex-start"; 60 break; 61 case "align-center": 62 ButtonLabelAlignment = "center"; 63 break; 64 case "align-right": 65 ButtonLabelAlignment = "flex-end"; 66 break; 67 case "align-full": 68 ButtonLabelAlignment = "space-between"; 69 break; 70 default: 71 ButtonLabelAlignment = "flex-start"; 72 break; 73 } 74 75 var btnStyleBlock = new System.Text.StringBuilder(); 76 77 // General Config 78 btnStyleBlock.Append(GenerateCssVar("btn-min-height", $"{mc.GeneralConfiguration.ButtonHeight}px")); 79 btnStyleBlock.Append(GenerateCssVar("btn-border-radius", $"{mc.GeneralConfiguration.RoundedCornerValue}px")); 80 81 // Button Config 82 btnStyleBlock.Append(GenerateCssVar("btn-border-width", $"{BC.BorderSize.ToString()}px")); 83 btnStyleBlock.Append(GenerateCssVar("btn-label-alignment", ButtonLabelAlignment)); 84 85 // Button Config Tab 86 btnStyleBlock.Append(GenerateCssVar("btn-bg-color", BC.ButtonColorConfiguration.BackgroundColor.GetColorCode(areaId))); 87 btnStyleBlock.Append(GenerateCssVar("btn-font-color", BC.ButtonColorConfiguration.FontColor.GetColorCode(areaId))); 88 btnStyleBlock.Append(GenerateCssVar("btn-border-color", BC.ButtonColorConfiguration.BorderColor.GetColorCode(areaId))); 89 90 // Button Config Hover tab 91 btnStyleBlock.Append(GenerateCssVar("btn-bg-color-hover", BC.ButtonHoverColorConfiguration.BackgroundColor.GetColorCode(areaId))); 92 btnStyleBlock.Append(GenerateCssVar("btn-font-color-hover", BC.ButtonHoverColorConfiguration.FontColor.GetColorCode(areaId))); 93 btnStyleBlock.Append(GenerateCssVar("btn-border-color-hover", BC.ButtonHoverColorConfiguration.BorderColor.GetColorCode(areaId))); 94 95 // Button Config Font Config 96 btnStyleBlock.Append(GenerateCssVar("btn-font-size", BC.FontConfiguration.FontSize)); 97 btnStyleBlock.Append(GenerateCssVar("btn-font-config-color", BC.FontConfiguration.Color.GetColorCode(areaId))); 98 btnStyleBlock.Append(GenerateCssVar("btn-font-line-height", BC.FontConfiguration.LineHeight)); 99 btnStyleBlock.Append(GenerateCssVar("btn-font-family", BC.FontConfiguration.FontConfiguration.FontFamily)); 100 btnStyleBlock.Append(GenerateCssVar("btn-font-weight", BC.FontConfiguration.FontWeight)); 101 btnStyleBlock.Append(GenerateCssVar("btn-font-transform", BC.FontConfiguration.FontStyle)); 102 103 return btnStyleBlock.ToString(); 104 } 105 106 public string GenerateCssVar(string name, string value) 107 { 108 if (!string.IsNullOrWhiteSpace(value)) { 109 return $"--{name}: {value};"; 110 } else { 111 return ""; 112 } 113 } 114 } 115 116 117 @{ 118 119 JumbotronContainer _data = Dynamicweb.Content.Services.Items.GetItem("JumbotronContainer", Pageview.CurrentParagraph.ItemId).ToCodeFirstItem<JumbotronContainer>() ?? new JumbotronContainer(); 120 121 var colorService = new ColorSwatchService(); 122 123 string backgroundClass = !string.IsNullOrWhiteSpace(_data.JumbotronConfiguration.BackgroundClass) ? string.Format("bg-{0}", _data.JumbotronConfiguration.BackgroundClass) : ""; 124 string JumbotronHeight = _data.JumbotronHeight + "px"; 125 126 string BackgroundHorizontalPosition = ""; 127 string BackgroundVerticalPosition = ""; 128 129 string QuickmenuWidth = _data.QuickmenuWidth + "px"; 130 int JumbotronListCount = _data.JumbotronList.Count; 131 132 string JumbotronCarouselClass = JumbotronListCount != 1 ? "jumbotron__carousel" : "jumbotron__no-carousel"; 133 string JumbotronCarouselMobClass = JumbotronListCount != 1 ? "jumbotron__carousel-mob" : "jumbotron__no-carousel-mob"; 134 135 var paragraphID = Pageview.CurrentParagraph.ID; 136 var JumbotronBackgroundClassName = ""; 137 138 string ShoutboxBackgroundColor = _data.JumbotronConfiguration.ShoutboxBackgroundColor; 139 string ShoutBoxGradient = _data.JumbotronConfiguration.ShoutboxBackgroundGradient; 140 141 string ShoutboxBackgroundImage = _data.JumbotronConfiguration.ShoutboxBackgroundImage; 142 143 string QuickmenuBackgoundImage = _data.JumbotronConfiguration.QuickmenuBackgroundImage; 144 145 ShoutboxBackgroundColor = colorService.GetHexColor(Pageview.AreaID, ShoutboxBackgroundColor); 146 147 bool infiniteLoop = _data.Infinite; 148 bool autoPlay = _data.AutoPlay; 149 bool controls = _data.AddControls; 150 int duration = _data.Duration; 151 bool showDots = _data.ShowDots; // If slider or multicolumn has to be in container or full widthof the page 152 153 } 154 155 <!-- 156 ***************************** 157 **** BEGIN DESKTOP SETUP **** 158 ***************************** 159 --> 160 161 <section class="jumbotron__playground jumbotron-mask jumbotron__playground-@paragraphID jumbotron--desktop jumboConfig--@_data.JumbotronConfigurationID @_data.CssClass @backgroundClass"> 162 163 <section class="@JumbotronCarouselClass" 164 data-dots="@showDots" 165 data-loop="@infiniteLoop" 166 data-autoplay="@autoPlay" 167 data-controls="@controls" 168 data-duration="@duration" 169 > 170 171 @foreach (var _item in _data.JumbotronList) 172 { 173 174 BackgroundHorizontalPosition = _item.BackgroundHorizontalPosition; 175 BackgroundVerticalPosition = _item.BackgroundVerticalPosition != "center" ? _item.BackgroundVerticalPosition : "middle"; 176 JumbotronBackgroundClassName = "jumbotron__image_background_" + paragraphID + "_" + _item.Id; 177 string jumbotronImage = _item.Image.Image.Replace("?x","&x"); 178 <div class="jumbotron @_item.CssClass" id="@_item.Id"> 179 180 <style> 181 182 @@media screen and (min-width: 994px) { 183 .@JumbotronBackgroundClassName { 184 background-image: url('/Admin/Public/GetImage.ashx?Image=@jumbotronImage&Crop=7&Format=webp&Width=1200&height=@_data.JumbotronHeight&Quality=-1&Compression=100'); 185 } 186 } 187 188 @@media screen and (min-width: 1200px) { 189 .@JumbotronBackgroundClassName { 190 background-image: url('/Admin/Public/GetImage.ashx?Image=@jumbotronImage&Crop=7&Format=webp&Width=2000&height=@_data.JumbotronHeight&Quality=-1&Compression=100'); 191 } 192 } 193 194 </style> 195 196 <figure class="jumbotron__image rellaxOff @BackgroundHorizontalPosition @BackgroundVerticalPosition @JumbotronBackgroundClassName"></figure> 197 198 @RenderShoutbox(_data, _item) 199 </div> 200 } 201 202 </section> 203 204 <!-- BEGIN QUICKMENU --> 205 206 @RenderQuickmenu(_data) 207 208 <!-- END QUICKMENU --> 209 210 <div class="jumbotron__shaper-container"><!--// 211 <svg width="100%" height="500" viewBox="0 0 1600 600" preserveAspectRatio="none"> 212 <defs> 213 <style> 214 .cls-1 { 215 fill: #cccccb; 216 } 217 218 .cls-2 { 219 fill: #fff; 220 opacity: 0.2; 221 } 222 223 </style> 224 </defs> 225 <title></title> 226 <path class="jumbotron__shaper-homepage" d="M2.59,495,237,553l122-48,132,54,360,16,262-48,176-90,154,120,112,12,206-102,159.79,65v71H1.56S1.31,493.72,2.59,495Z" /> 227 <polygon class="cls-2" points="359 505 317 599 491 559 359 505" /> 228 <polygon class="cls-2" points="1289 437 1443 557 1177 601 1289 437" /> 229 <polygon class="cls-2" points="1761 467 1696.44 604.28 1920.8 603 1920.8 532.03 1761 467" /> 230 </svg> 231 <svg width="100%" height="600" viewBox="0 0 2000 600" preserveAspectRatio="none"> 232 <clipPath id="myClip"> 233 <path class="cls-1" d="M1999.57,425c-123.24,53.94-329.82,96.6-581.35,119.35q33.6-6.59,65.7-14.19c104.82-24.86,197.33-58,276-98.78,21.37-11.08,49.25-53.51,49.25-53.51C1609,504.41,1328.64,545.78,1128.7,558.21c-31.7,2-62.42,3.29-91.8,4.12q-18.23.13-36.6.13c-81.34,0-160.65-1.95-237.08-5.65-16.15-1.19-25.6-1.31-25.6-1.31C416.39,538.15,148.8,489.67,1,425H.3V600h2000V425Z"></path> 234 </clipPath> 235 </svg> 236 //--> 237 238 <!--// 239 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" height="0" width="0" viewBox="0 0 2000 600" preserveAspectRatio=""> 240 <clipPath id="myClip"> 241 <path class="st0" d="M0,0v325h0.2C37.1,389.7,104,438.2,184.3,455.5c0,0,2.4,0.1,6.4,1.3c19.1,3.7,38.9,5.7,59.3,5.7 242 c3.1,0,6.1,0,9.2-0.1c7.3-0.8,15-2.1,23-4.1c50-12.4,120.1-53.8,170.1-180.3c0,0-7,42.4-12.3,53.5c-19.7,40.8-42.8,73.9-69,98.8 243 c-5.4,5.1-10.8,9.8-16.4,14.2C417.4,421.6,469,378.9,499.8,325h0.2V0H0z" /> 244 </clipPath> 245 </svg> 246 //--> 247 248 <!--<img src="https://images.unsplash.com/photo-1592006256125-1e7622ead3b0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt="Photographer in a market." height="1000" width="1000" /> 249 <svg width="0" height="0"> 250 <clipPath id="svgClip" clipPathUnits="objectBoundingBox"> 251 <path d="M0.75815095, 0.0579477769 C0.879893708, 0.187288937 0.902165272, 0.677587654 0.799370955, 0.785996249 C0.627963035, 0.966765889 0.26163708, 0.91434951 0.111342491,0.755791573 C-0.0332137967,0.603287436 -0.035795248,0.382887577 0.0965066612,0.173955315 C0.200239457,0.0101396315 0.648923894,-0.0580965318 0.75815095,0.0579477769 Z"></path> 252 </clipPath> 253 </svg> 254 <style> 255 .jumbotron-mask { 256 clip-path: url(#svgClip); 257 width: 18em; 258 height: 18em; 259 object-fit: cover; 260 display: block; 261 margin-right: auto; 262 margin-left: auto; 263 } 264 </style>--> 265 </div> 266 267 </section> 268 269 <!-- 270 *************************** 271 **** END DESKTOP SETUP **** 272 *************************** 273 --> 274 275 <style> 276 @_data.JumbotronConfiguration.GetJumbotronStylesheet() 277 </style> 278 279 <!-- 280 **************************** 281 **** BEGIN MOBILE SETUP **** 282 **************************** 283 --> 284 285 <section class="jumbotron__playground jumbotron__playground-@paragraphID jumbotron--mobile @_data.CssClass"> 286 287 <section class="@JumbotronCarouselMobClass" 288 data-dots="@showDots" 289 data-loop="@infiniteLoop" 290 data-autoplay="@autoPlay" 291 data-controls="@controls" 292 data-duration="@duration" 293 > 294 @{ int mobIndex = 0; } 295 @foreach (var _item in _data.JumbotronList) 296 { 297 298 BackgroundHorizontalPosition = _item.BackgroundHorizontalPosition; 299 BackgroundVerticalPosition = _item.BackgroundVerticalPosition != "center" ? _item.BackgroundVerticalPosition : "middle"; 300 string lazyLoad = mobIndex > 0 ? "loading='lazy'" : ""; 301 string jumbotronImage = _item.Image.Image.Replace("?x","&x"); 302 <div class="jumbotron @_item.CssClass"> 303 304 <!-- BEGIN IMAGE --> 305 306 <figure class="jumbotron__image-container"> 307 <picture class="jumbotron__image w-full h-full"> 308 <source media="(max-width: 400px)" srcset="/Admin/Public/GetImage.ashx?Image=@jumbotronImage&Crop=7&Format=webp&Quality=-1&Width=400&Compression=90"> 309 <source media="(max-width: 500px)" srcset="/Admin/Public/GetImage.ashx?Image=@jumbotronImage&Crop=7&Format=webp&Quality=-1&Width=500&Compression=90"> 310 <source media="(max-width: 600px)" srcset="/Admin/Public/GetImage.ashx?Image=@jumbotronImage&Crop=7&Format=webp&Quality=-1&Width=600&Compression=90"> 311 <source media="(max-width: 700px)" srcset="/Admin/Public/GetImage.ashx?Image=@jumbotronImage&Crop=7&Format=webp&Quality=-1&Width=700&Compression=90"> 312 <source media="(max-width: 994px)" srcset="/Admin/Public/GetImage.ashx?Image=@jumbotronImage&Crop=7&Format=webp&Quality=-1&Width=994&Compression=90"> 313 <img src="/Admin/Public/GetImage.ashx?Image=@jumbotronImage&Crop=7&Format=webp&Width=400&Quality=-1&Compression=90" width="1980" height="500" alt="@_item.Image.ImageAlt" @lazyLoad /> 314 </picture> 315 </figure> 316 317 <!-- END IMAGE --> 318 <!-- BEGIN SHOUTBOX --> 319 320 @RenderShoutbox(_data, _item) 321 322 <!-- END SHOUTBOX --> 323 </div> 324 mobIndex++; 325 } 326 327 </section> 328 329 <!-- BEGIN QUICKMENU --> 330 331 @RenderQuickmenu(_data) 332 333 <!-- END QUICKMENU --> 334 335 </section> 336 337 <!-- 338 ************************ 339 *** END MOBILE SETUP *** 340 ************************ 341 --> 342 343 <style> 344 .jumbotron__playground, 345 .jumbotron { 346 height: auto; 347 } 348 349 @@media screen and (min-width: 991px){ 350 .jumbotron__playground-@paragraphID .jumbotron__carousel, 351 .jumbotron__playground-@paragraphID .jumbotron { 352 height: @JumbotronHeight; 353 overflow: hidden; 354 } 355 356 .jumbotron__playground-@paragraphID .jumbotron__container { 357 width: 100%; 358 } 359 360 .jumbotron__playground-@paragraphID .quickmenu { 361 width: @QuickmenuWidth; 362 } 363 364 .jumbotron__playground-@paragraphID .jumbotron__no-carousel, 365 .jumbotron__playground-@paragraphID .jumbotron__carousel { 366 width: calc(100% - @QuickmenuWidth); 367 368 } 369 370 .jumbotron__playground-@paragraphID .jumbotron__shoutbox { 371 background-color: @ShoutboxBackgroundColor; 372 @if (!string.IsNullOrWhiteSpace(ShoutBoxGradient)) { 373 374 <text> @ShoutBoxGradient </text> 375 376 } 377 @if (!string.IsNullOrWhiteSpace(ShoutboxBackgroundImage)) { 378 379 <text> 380 background-image: url('@ShoutboxBackgroundImage'); 381 </text> 382 383 } 384 } 385 386 .jumbotron__playground-@paragraphID .quickmenu { 387 @if (!string.IsNullOrWhiteSpace(QuickmenuBackgoundImage)) { 388 389 <text> 390 background-image: url('@QuickmenuBackgoundImage'); 391 </text> 392 393 } 394 } 395 396 397 } 398 </style> 399 400 @helper RenderShoutbox(JumbotronContainer _data, JumbotronListItem _item) 401 { 402 string ShoutboxFullHeightClass = _data.ShoutboxFullHeight ? "fullheight" : ""; 403 string ShoutboxBackgroundTransparentClass = _data.ShoutboxBackgroundTransparent ? "transparent" : ""; 404 405 string ShoutboxHorizontalPositionClass = _data.ShoutboxHorizontalPosition; 406 string ShoutboxVerticalPositionClass = _data.ShoutboxVerticalPosition != "center" ? @_data.ShoutboxVerticalPosition : "middle"; 407 408 <section class="jumbotron__container container @ShoutboxHorizontalPositionClass @ShoutboxVerticalPositionClass "> 409 410 @if (_item.HasShoutbox) 411 { 412 <div class="jumbotron__shoutbox @ShoutboxBackgroundTransparentClass @ShoutboxFullHeightClass"> 413 <section class="jumbotron__shoutbox-header"> 414 415 @_item.SubHeader.HeaderFormatted("jumbotron__subheading") 416 @_item.Header.HeaderFormatted("jumbotron__heading") 417 418 @if (!string.IsNullOrWhiteSpace(_item.Content.Text)) 419 { 420 <div class="jumbotron__shoutbox-intro">@_item.Content.Text</div> 421 } 422 423 @RenderButton(_item.Button, Pageview) 424 425 </section> 426 </div> 427 } 428 </section> 429 } 430 431 @helper RenderQuickmenu(JumbotronContainer _data) 432 { 433 int quickmenuWidth = _data.QuickmenuWidth; 434 435 if (quickmenuWidth > 0) 436 { 437 <div class="quickmenu"> 438 <h2 class="quickmenu__header">@_data.QuickmenuHeader</h2> 439 <nav class="quickmenu__list"> 440 @foreach (var _link in _data.QuickmenuLinks) 441 { 442 var highlightedClass = _link.Highlighted ? "highlighted" : ""; 443 var targetLink = _link.NewWindow ? "target='_blank'" : ""; 444 445 <a href="@_link.Link" class="quickmenu__link @highlightedClass" @targetLink> @_link.Name </a> 446 } 447 </nav> 448 </div> 449 } 450 } 451
Fragmentation slows adoption and increases exposure
When AI grows without a framework, so do the risks
In many organisations, AI usage emerges through separate tools and initiatives. Employees experiment, teams solve issues locally and IT only gains visibility later. This is understandable, but it is not scalable.
Without clear insight into use cases, data flows, ownership and security, risks arise around GDPR, IP and compliance. As long as the foundation is missing, AI remains stuck in pilots instead of delivering structural process improvement.
What we see with our clients
The main challenges you are facing
- No complete overview of AI tools, use cases and data usage
- Unclear ownership, governance and management
- Initiatives without a clear business case or follow-up
- Integration with M365, CRM, ERP and SharePoint takes too much time
- Uncertainty about security, compliance and data quality
- Limited explainability, slowing down trust and adoption
You can only accelerate responsibly once these points are clearly addressed.
Many organisations want to move forward with AI but lack a factual starting point. What is happening today? Where are the risks, where is the value and what is logical to prioritise first? Our AI Scan maps this out in a structured way and prevents decisions based on assumptions.
AI Scan. First gain clarity. Then make the right choices.
Clarity, target architecture and roadmap in one approach
AI Scan: from baseline to direction and priority
We start with an AI Scan. This provides a factual starting point: how AI is currently being used, where the main risks are and which opportunities are most promising.
We map your AI and IT landscape, including data flows, integrations and preconditions. We then design a manageable AI target architecture and translate it into a prioritised roadmap with concrete projects, scope, effort and expected impact.
Within your own environment, with governance and logging from day one
We then deliver AI agents that truly work
Based on the AI Scan, we design and implement targeted AI agents for processes such as sales, HR, operations and IT support. Each agent has a clearly defined task and delivers predictable output that is directly usable in practice.
We embed security, privacy, roles, permissions and logging into both the design and implementation. Where decisions have impact, we explicitly include human-in-the-loop. This ensures AI remains explainable, controllable and auditable.
Practical, modular and scalable
Solutions and processes we focus on
- Sales and account preparation
- HR and recruitment support
- Operations and IT support
- Management information and decision-making
- Marketing and content
- Operations, procurement and logistics
Small steps, immediate value
Concrete applications in practice
- Sales starts every client conversation with an automated client briefing and action list
- HR teams structure screening, interviews and follow-up within clear frameworks
- IT support classifies and prioritises tickets with consistent solution proposals
- Managers ask questions in plain language based on ERP, CRM and BI data
- Operations identifies deviations in inventory, delivery times and orders, including suggested actions
AI Scan
Inventory of AI usage within the organisation, including risks and opportunities.
Responsible 'AI Framework'
Clear agreements and policies, data boundaries and human oversight.
Tooling & Agents
Aligned with the different roles within the organisation.
Training and Adoption
Ready to take control of AI?
Start with clarity. Then build with focus.
Do you want to use AI structurally, without uncontrolled growth or black boxes? We create control with an AI Scan and then develop AI agents that operate securely within your processes. Get in touch and take the first step towards manageable, measurable AI in your organisation.