Articles
Brickhouse Guitars
Hozen Blue Label 45 21031045 1 Demo by Roger Schmidt
Brickhouse Guitars
Hozen Blue Label 189 21090186 1 Demo by Roger Schmidt
Brickhouse Guitars
Hozen Blue Label 104 21071583 1 Demo by Roger Schmidt
KW Predatory Volley Ball
$3000 for food4kids. Thank you Predators
♦
Read full story for latest details.Tag(s): Home
Code Like a Girl
How to Use SVG as a Placeholder, and Other Image Loading Techniques
♦
Improve performance and user experience
Continue reading on Code Like A Girl »
Code Like a Girl
AI in Software Development Unconference
♦
Expertise and passion for tech unleashed
Continue reading on Code Like A Girl »
Code Like a Girl
The Luddites Were Right
♦
AI is rubbish, but it’ll still take your job
Continue reading on Code Like A Girl »
Code Like a Girl
Nurture Interconnectedness, and Other Actions for Allies
Now and then, I read something on social media that makes me think deeply about my work. The latest? A post by inclusion and belonging strategist Rachel Ann Williams, where she wrote,
“The past decade of DEI work was about difference — celebrating identity, illuminating disparities, and amplifying voices too often ignored. It was a time of research, reckoning, learning, and unlearning. Of allyship in its early forms.”
Williams added, “But the next decade will be defined by something more profound: our shared humanity.”
She believes that action across lines of difference will be the driving force moving forward. “We’ll still honor the truth of our lived experiences, but we’ll also lean harder into our interconnectedness. The future of this work will be about cross-cultural coalitions, emotional intelligence, empathy in action, and building communities of care.”
(On a related note, I’ve been reading about how some colleges and universities are embracing pluralism as a strategy for what comes after DEI. Specifically, they are designing programs to support a community of people with differing points of view. Source: The New Yorker)
How might you nurture interconnectedness in your workplace?
Keep reading for some specific ideas.
Share this action on Bluesky, LinkedIn, Instagram, Threads, or YouTube.
2. Build on others’ pointsA few years ago, I remember reading a New York Times Daily newsletter that highlighted what’s been happening in the U.S. Supreme Court. Adam Liptak, who covers SCOTUS for the newspaper, shared:
“I was at the court in person for several arguments this month, and so far the justices seem to be making a point of trading quips and acknowledging points of agreement. You hear them saying things like, As Justice So-and-so was saying or, Let me build on that point. It seems to be a conscious effort to rebuild relationships that have become a little frayed.”
Let’s all strive to acknowledge points of agreement with our colleagues and build relationships (even if they aren’t frayed). A simple “Let me build on what So-and-So was saying” could go a long way toward a stronger feeling of interconnectedness.
3. Listen intently (with or without eye contact)While doing research for my book Better Allies, I heard from many women that their male supervisor would look at their peers when asking questions, ignoring them (the only woman) in small group meetings. Or, in 1-on-1 sessions, their manager would look at the floor or out the window. As a result, they felt unwelcome. At times, even invisible.
On the other hand, I’ve learned that autistic people may find eye contact uncomfortable. And in certain cultures, eye contact can be a sign of disrespect, so people look downward instead.
Is there a way to reconcile this paradox?
I think so.
Last week, Dionn Schaffner, a Chief Diversity Office and SVP of Social Impact, wrote about some small shifts that can have a significant inclusion impact for neurodiverse individuals.
One is that “Eye contact isn’t a universal sign of respect or engagement. Listening matters more than where your eyes land.”
Whether we are comfortable with eye contact or not, let’s ensure we’re sending signals that we’re listening intently to everyone in the room. For example, we can nod, lean towards the person speaking, ask clarifying questions, or take notes on what they’re saying.
4. Attend employee resource group meetingsIn 2021, a working group of DEI experts from companies, educational institutions, and nonprofits collaborated to create a blueprint for action: The Action to Catalyze Tech (ACT) Report. At the time, it was commended by the White House, endorsed by the NAACP, and signed by dozens of organizations.
One of its recommendations is for individuals to interact personally and continuously with employees from underrepresented groups and employee resource groups (ERGs).
As the report explains, “You can learn and make a huge impact by showing up for your employees to support ERGs or simply hear from employees from underrepresented groups about their lived experiences, inside and outside work.”
And, by doing so, I bet you’ll find some things you have in common with coworkers of different backgrounds.
5. Community Spotlight: Ask yourself, “Why am I talking?”This week’s spotlight on an ally action from the Better Allies community is from a newsletter subscriber who wrote,
“I’m working through the book Say What You Mean: A Mindful Approach to Nonviolent Communication by Oren Jay Sofer. It is excellent with very accessible language and practical ideas on re-training one’s communication to better connect with others.”
Because of their recommendation, I started reading Sofer’s book. It’s fantastic.
Here’s one thing I learned from it, relevant to today’s newsletter about interconnectedness: Be mindful of “choice points” or moments of awareness in any mode of communication where we decide to speak or listen.
For example, when checking your inbox or social media feeds (aka “listening”), pause before replying to consider whether or not you want to “speak.” Ask yourself if this is the right time and if it would be helpful to wait or say nothing at all.
Similarly, during a live conversation, create a choice point by saying, “Let me think about that for a moment.” Or “Can we pause for a sec? I want to gather my thoughts.”
Sofer also quoted a colleague who uses pauses to ask himself, “Why Am I Talking?” Which just so happens to have the appropriate acronym of “WAIT.” 😍
If you’ve done something to nurture interconnectedness or any kind of action as an ally, please reply to this email and tell me about it. And mention if I can quote you by name or credit you anonymously in an upcoming newsletter.
That’s all for this week. I wish you strength and safety as we all move forward,
Karen Catlin (she/her), Author of the Better Allies® book series
pronounced KAIR-en KAT-lin, click to hear my name
Copyright © 2025 Karen Catlin. All rights reserved.
Being an ally is a journey. Want to join us?
- Follow @BetterAllies on Bluesky, Instagram, Medium, Threads, or YouTube. Or follow Karen Catlin on LinkedIn
- This content originally appeared in our newsletter. Subscribe to “5 Ally Actions” to get it delivered to your inbox every Friday
- Read the Better Allies books
- Form a Better Allies book club
- Get your Better Allies gear
- Tell someone about these resources
Together, we can — and will — make a difference with the Better Allies® approach.
♦♦Nurture Interconnectedness, and Other Actions for Allies was originally published in Code Like A Girl on Medium, where people are continuing the conversation by highlighting and responding to this story.
Greater Kitchener Waterloo Chamber of Comerce
Business of the Year Award Winner (Over 50 Employees): NDI (Northern Digital Inc.)
On Thursday, March 20, 2025, the Greater Kitchener Waterloo Chamber of Commerce hosted the 2025 Business Excellence Awards Gala, presented by Cowan Insurance Group. The Waterloo Region business community, local dignitaries, and community ambassadors came together to honour the extraordinary contributions of more than 130 nominees across 14 categories.
Congratulations to NDI (Northern Digital Inc.) for winning the Business of the Year Award (Over 50 Employees). This award goes to the business that has established themselves as a notable contributor to Waterloo Region’s local economy, commitment to innovation, and a business that truly inspires the next generation of talent.
NDI (Northern Digital Inc.) has been a trailblazer in the 3D optical and electromagnetic tracking technology sector for nearly 45 years, and their sustained innovation has solidified their position as a leader in the industry. With a workforce of nearly 300 professionals, NDI’s growth has been remarkable, maintaining an average annual growth rate of 12% over the past 15 years. Their commitment to innovation is especially evident in the Waterloo region, where the company has maintained a dominant presence, generating over 85% of their total revenue in 2024. Outside the Region, NDI’s innovations have been integrated into over 90% of North America’s advanced surgical navigation systems.
But for NDI, Waterloo Region is home. Last year, NDI employees raised over $3,200 for the Send ‘Em Off Smiling foundation, organized food drives, and supported local healthcare initiatives, including significant contributions to Hospice Waterloo Region. Their dedication to improving the community is further exemplified by their support for local educational programs, environmental sustainability efforts, and initiatives such as paid volunteer time and mental health resources for employees. Their core values continue to include a focus on social responsibility and community well-being.
The post Business of the Year Award Winner (Over 50 Employees): NDI (Northern Digital Inc.) appeared first on Greater KW Chamber of Commerce.
House of Friendship
A Lifeline of Support
Your care and compassion is helping Zapour and Meghety find a new community of support in Canada
When Meghety first came to Canada, she found it hard to find a place to belong.
If you met Meghety today, all you would see is her wonderful smile. She would tell you how much she loves visiting her favorite place in the world, at our Sunnydale Community Centre.
But it wasn’t that long ago that Meghety found each day a struggle after leaving her home country of Syria behind.
“It took a while for Meghety to get used to her new home,” said her mother, Zapour. “I worried about her and wanted more for her.”
Meghety, now 29, lives with some developmental challenges. And while she is fluent in Armenian and Arabic, she is still learning English, making it more challenging to make friends in her new country. In her first nine years here, Meghety often stayed at home with her family, afraid to venture out her doors.
But when Meghety discovered Sunnydale Community Centre, her life was transformed.
Nazmi, one of our incredible team members, saw Meghety’s potential and signed her up as a volunteer. Ever since, Sunnydale has become Meghety’s home away from home and a bright spot in her day.
I love everything about Sunnydale. I like to help, I love Marwa, Nazmi and Ola – they are all my friends here. – Meghety
Every day, families like Meghety’s come through our doors because they have nowhere else to go. For some, it’s about finding a place to belong and grow. For others, it’s about receiving the basic support they need to survive. In each case, it’s a lifeline.
Your faithful support of Neighbourhoods programs is ensuring people like Meghety, and their families, get the help they need when they need it.
Meghety comes every Thursday morning to help hand out food to other families in the neighbourhood. She organizes the canned food that arrives early in the morning, breaks down boxes for recycling, and visits with other volunteers. When community members arrive, Meghety is there with her bright smile, greeting them and providing the food they need to get through the week.
Meghety takes pride in her volunteer work. She knows she is making a difference. And after a hard day’s work, Meghety can take some of her favourite food home, another source of pride for her.
The life that Meghety and her family live today is in stark contrast to the journey they endured to get here. Twelve years ago, they fled war-torn Syria, hoping for a better life.
Back in Syria, Meghety represented her country in Egypt at the Special Olympics, winning a bronze medal in swimming. She had a happy life in her home country.
But when the war started, the peaceful life they once knew was gone forever.
“We lived in Syria for one year without electricity of heat,” said Zapour. “It was very cold in the winter. We only left our home when we had to. It wasn’t safe.”
There are so many families like Meghety’s leaving behind the world they once knew. They have to start over. But how can they begin again without help? Without hope?
Today, Meghety and her family are adjusting to life in Canada, grateful for the opportunities living here gives them. They all live together, as one big family – all with Zapour’s mother-in-law and sister’s family.
Together, Zapour and her sister run a home daycare.
“It brings us so much joy to work with the children,” said Zapour. “And Meghety also helps us with the daycare and the kids love her.”
Thank you for making new beginnings possible for family’s like Meghety’s. Your support of Neighbourhoods programs is ensuring that community members in need have a safe place to start over.
The post A Lifeline of Support appeared first on House Of Friendship.
Elmira Advocate
ONTARIO STEPS IN TO BRING SCHOOL BOARDS UNDER CONTROL
Wow the shame! How awful does a school board have to be to actually have the province step in and take control? Keep in mind these boards are democratically elected by the same twits who elect both Liberals and Conservatives provincially and federally. Yes that would be you and I and frankly sometimes I worry about your competence as a voter.
One board allegedly is guilty of financial mismanagement and three others are being investigated for the same. The fifth board you really have to admire their chutzpah. They are being ordered to repay costs for a trip to Italy to buy art. Man you can't make this stuff up. With tight budgets, provincial deficits and constant complaining about underfunding education how does a board O.K. a junket to Italy to buy art ?
The article in yesterday's K-W Record is titled "Ontario takes control of London school board, launches probes of three others" and was written by Allison Jones and Liam Casey.
Likely last month I had suggested here that our very own Waterloo Region District School Board (WRDSB) was in need of the province stepping in to get them back on track. Now by getting back on track I was not suggesting financial mismanagement as much as a mismanagement of their core values and goals. We have all seen years and decades of sniping, back stabbing , tattling and deflections of focus away from reading, writing and arithmetic. The ongoing Caroline Burjowski court battles are a prime example. The Board could have and should have settled them back in the beginning instead of letting them fester. Festering however seems to be the prime strategy of this board as they spend taxpayers money in order to bury other taxpayers who have had enough of their arrogance, entitlement and refusal to deal in good faith with dissenting opinions and parties.
Capacity Canada
Introducing Capacity Canada’s 2024 Annual Report
♦
Take a look at Capacity Canada’s 2024 Annual Report, showcasing the impactful ways we support non-profit and charitable organizations in making a difference.
Your thoughts and questions mean the world to us—I’d love to hear what you think!
Thank you for joining us in our mission of bringing together the ideas, people, and resources that drive social innovation forward.
Warmly,
Cathy Brothers
cathy@capacitycanada.ca
♦
CLICK HERE TO READ ONLINE CLICK HERE TO DOWNLOAD PDF
The post Introducing Capacity Canada’s 2024 Annual Report appeared first on Capacity Canada.
Hoesy, Michalos & Associates
How to Get Out of Gambling Debt in Canada
Facing gambling debt can feel overwhelming, isolating, and stressful, but you’re not alone. Single even sports betting was legalized in 2021 in Canada. Unfortunately, it’s now creating serious debt problems for many people who gamble on these events. Fortunately, there are clear and effective ways to deal with gambling debt in Canada, including consumer proposals and bankruptcy.
Gambling Debt is More Common Than You ThinkGambling debt usually starts with small wagers, such as lottery tickets, scratch tickets, or online card games. Over time, what seemed like harmless entertainment can spiral into significant financial trouble. According to Statistics Canada, around two-thirds of Canadians aged 15 or older have participated in some form of gambling, highlighting how widespread gambling activities have become.
The truth is, anyone can find themselves struggling with gambling debt, often quietly. It’s essential to know that Licensed Insolvency Trustees (LITs) provide judgment-free help, offering compassionate guidance to those needing debt relief.
Why Gambling Debt HappensSeveral factors can lead individuals into serious gambling debt:
-
Easy Credit Access: Credit cards and payday loans make funds readily available, facilitating continuous gambling even when personal resources are exhausted.
-
Chasing Losses: Many gamblers continue betting in hopes of recovering previous losses, inadvertently deepening their financial problems.
-
Mental Health Connections: Issues such as anxiety, depression, or attention deficit disorders (ADD) can contribute to gambling behaviors.
If you’re dealing with gambling debt, it’s important to know that solutions are available, and it’s never too late to start turning things around. Below, we’ve outlined practical steps you can take right away to start managing your debt and regain control of your financial future.
Protect Yourself FinanciallyYour first step is to acknowledge you have a gambling problem and take steps so your financial situation does not become worse:
-
Freeze Access to Credit: Prevent further debt accumulation by limiting your access to new credit sources or freezing existing credit accounts.
-
Self-Exclusion Programs: Voluntarily exclude yourself from online and physical gambling locations.
-
Talk With a Professional: Seek professional help to address underlying gambling addiction issues. If you are struggling with debt repayment, consider contacting a Licensed Insolvency Trustee. LITs are experienced in helping people find debt solutions and offer credit counselling advice is a non-judgmental manner.
Gambling debts are generally treated like other unsecured debts in Canadian insolvency proceedings. This provides a fresh start for people struggling with gambling-related financial problems.
When talking with your LIT, they can help you explore two primary options to deal with gambling debt:
-
Bankruptcy: Bankruptcy does discharge gambling debts in Canada, however you must disclose to your LIT if the primary cause of your debts was due to gambling. In some cases the courts may require additional conditions for you to obtain your bankruptcy discharge. It is rare for the court to refuse a bankruptcy discharge due to gambling debts alone.
-
Consumer Proposal: Unlike bankruptcy, there’s no court process involved when filing a consumer proposal – it’s more of a negotiation directly with your creditors. Basically, you work with a Licensed Insolvency Trustee who helps you put together an offer to pay back a portion of what you owe (often 30-50%) over a period of up to five years. As long as creditors holding the majority of your debt agree to the proposal, it becomes binding for all unsecured creditors – including gambling debts. This means you can settle your gambling debts for less than you owe while avoiding the more severe consequences of bankruptcy. Plus, you get to keep your assets, and the payment plan is designed to be manageable based on your actual income. Many people find consumer proposals less stressful since they provide debt relief without the stigma or restrictions that come with bankruptcy.
Beau Humphreys, featured on our Debt Free in 30 podcast, began gambling as a child, initially buying lottery tickets. By university, Beau’s gambling escalated to online card games and sports betting, funded by easy access to credit cards. Eventually, he amassed $40,000 in gambling-related debts.
Beau chose a consumer proposal, reducing his debt significantly and fixing monthly payments at an affordable amount ($300 per month over 50 months). He credits the consumer proposal with giving him the financial stability to address his gambling triggers and rebuild his life and credit.
During his consumer proposal, Beau benefited significantly from credit counselling sessions. Our credit counsellors provided valuable financial education, helping him better understand how to manage money, rebuild his credit score responsibly, and recognize triggers for his gambling issues. Through counselling, Beau developed healthier financial habits, giving him the tools and confidence needed to maintain financial stability long after completing his proposal.
Is a Consumer Proposal Right for You?A consumer proposal may be ideal if you want to:
-
Keep your assets like your home and vehicle.
-
Reduce the total amount owed without interest.
-
Have fixed and manageable monthly payments.
-
Rebuild your credit faster.
Licensed Insolvency Trustees can guide you through the consumer proposal process, clearly explaining every step and provide advice on how to get your finances back on track.
Where to Get Help in OntarioAt Hoyes Michalos, our Licensed Insolvency Trustees offer professional and empathetic advice, guiding you to the best debt relief solution tailored specifically for your needs. Hoyes Michalos has helped thousands of Canadians successfully eliminate their debt with a 99% proposal acceptance rate.
You’re not alone in your struggle with gambling debt.
Book Your Free, No-Obligation Consultation Today and reduce the financial impact of problem gambling.
The post How to Get Out of Gambling Debt in Canada appeared first on Hoyes, Michalos & Associates Inc..
James Davis Nicoll
Full Time Help / The Ministry of Time By Kaliane Bradley
The Ministry of Time by Kaliane Bradley is a stand-alone time travel novel.
Commander Graham Gore was just one of the hapless explorers in the Franklin Expedition1, which was attempting to find a Northwest Passage across the top of Canada. He appears in the history books as one of the casualties of the ill-fated expedition. In this novel he is given an afterlife… of sorts.
…
Brickhouse Guitars
Boucher HG56 M IN 1309 12FTB Demo by Roger Schmidt
The Backing Bookworm
The Body in the Library
Confession Time: I've never read an Agatha Christie book. I know, shameful. All I know of Dame Christie are the names of two of her most popular main characters - Poirot and Miss Jane Marple, that her books are British mysteries with inventive twists, and good sleuthing and that she disappeared for 11 days and never explained what happened to her.
So, I grabbed this book from the library, an early book in the series (it seems some webpages say it's the 2nd book and others the 3rd), to see what all the fuss was about. The story is set in a sleepy little English town where murder comes to call. Miss Marple, based on her earlier sleuthing experience, is asked by the owner of the house in which the body is found to share her newfound 'expertise'.
Readers get introduced to a LOT of secondary characters and Christie describes a small English village - complete with gossipy busybodies, nosey neighbours and secrets. What surprised me was that Miss Marple, the main character of this series, plays a very secondary role in this book. Sure, she saves the day with her deduction, but the actual sleuthing was left to the police.
This wasn't quite the 'wow' read I was expecting from Dame Christie, but it was a very quick read at only 160 pages that had some misdirection and a decent (if not fully explained) final twist. Overall, I was a little underwhelmed by my first foray into the world of Miss Marple (and Christie).
My Rating: 3 starsAuthor: Agatha ChristieGenre: MysterySeries: Miss Marple 2Type and Source: Hardcover from public libraryPublisher: Harper CollinsFirst Published: 1942Read: April 22-24, 2025
Book Description from GoodReads: It’s seven in the morning. The Bantrys wake to find the body of a young woman in their library. She is wearing evening dress and heavy make-up, which is now smeared across her cheeks.
But who is she? How did she get there? And what is the connection with another dead girl, whose charred remains are later discovered in an abandoned quarry?
The respectable Bantrys invite Miss Marple to solve the mystery… before tongues start to wag.
♦
Github: Brent Litner
brentlintner starred LibreHardwareMonitor/LibreHardwareMonitor
Libre Hardware Monitor is free software that can monitor the temperature sensors, fan speeds, voltages, load and clock speeds of your computer.
C# 6.4k 14 issues need help Updated Apr 22
Github: Brent Litner
brentlintner starred liquidctl/liquidctl
Cross-platform CLI and Python drivers for AIO liquid coolers and other devices
Python 2.3k Updated Apr 13
Github: Brent Litner
brentlintner starred ColinIanKing/stress-ng
This is the stress-ng upstream project git repository. stress-ng will stress test a computer system in various selectable ways. It was designed to …
C 2k Updated Apr 25
Jane's Walk Waterloo Region
Marvelous Mt. Hope-Breithaupt Park: From Industrial Past to Innovative Present
When: Sunday, May 4th 2025, 1:00 – 2:30 pm
Meeting Point: 72 St. Leger Street (corner of St. Leger & Breithaupt Streets), Kitchener
Walk Leader: Lane Burman, Ted Parkinson
Ted Parkinson and Lane Burman will lead this walk through the Marvelous Mt. Hope-Breithaupt Park (MHBP) neighbourhood. In only a few blocks, just over a kilometre, we will discuss the history and development of our streets, businesses and industries. MHBP has been central to manufacturing furniture, buttons, tanning, pianos, stereos and more. And it is now a large part of the “Innovation” district with software companies and two stops on the ION route. As always, there will be time to meet and talk with neighbours along the way and everyone is welcome to share their stories..
KW Predatory Volley Ball
Congratulations Cameron Hutt. 18U Grand Prix All Star
♦
Read full story for latest details.Tag(s): Home
Child Witness Centre
Thousands of Local Youth Inspired at 2025 Youth Symposium
A total of over 3,000 grade 8 students and their teachers came from nearly 50 local public, Catholic, and independent schools for the 18th annual edition of this unique program. The three-day event took place at Galaxy Cineplex Cinemas on April 15 in Guelph and April 16 and 17 in Waterloo.
You can see photos from the event in this slideshow video on our social media pages!
In the media! Check out this wonderful GuelphToday article created by Santana Bellantoni.
Positive Messages DeliveredThe multitude of youth in attendance heard from an amazing line-up of professional speakers. They included a magician, acrobat, stunt person, boxer, wrestler, former police sergeant, and more. What do all these speakers have in common? A big heart for making a difference in the lives of young people.
The wide variety of topics included dreaming big, setting SMART goals, resiliency, overcoming challenges, healthy dating relationships, volunteering, school spirit, and showing kindness. The energy and enthusiasm in the theatres was palpable.
It was also a special opportunity to learn from our Child Witness Centre representatives about the work we do in Waterloo Region, Guelph, and Wellington County. Last year alone, we supported 1,088 child and youth victims of abuse and crime through the criminal justice system, along with 827 caregivers.
Why The Program MattersThis big multi-day event is focused on inspiring, educating, and encouraging youth at an important time in their personal development. The program is strategically scheduled in April to reach grade 8 students before they begin high school later in the year.
The feedback from students and teachers is overwhelmingly positive.
- One youth shared what they learned is "Strive for who you want to be. Never give up. Don't listen to anyone who tries to get in your way." Another student said their biggest takeaway is, "As long as you stay resilient, you can accomplish amazing things."
- A teacher stated, "All the speakers delivered an excellent and important message that students this age need to hear." Another teacher said they’ll continue discussing in class, "Focus on the positive. Don't dwell on the negative. Mindset can change perspective."
We would like to thank all our wonderful event sponsors (found below), volunteers, presenters, local police, and everyone else who helped make this very meaningful event a huge success! With the support of the community, over 40,000 students have now been impacted since the program began in 2003.
At Child Witness Centre, we're already looking forward to our 2026 Youth Symposium! We feel it's difficult to overstate the value found in building up young people through this initiative. It prompts countless positive outcomes in young lives, and a ripple effect of benefits for years to come.
Learn more about Youth Symposium here!
2025 Youth Symposium Sponsors EVENT SPONSOR ♦ SPEAKER SPONSORS ♦ ♦ VENUE & A/V SPONSORS ♦ ♦ FOOD SPONSORS ♦ ♦The post Thousands of Local Youth Inspired at 2025 Youth Symposium first appeared on Child Witness Centre.
Greater Kitchener Waterloo Chamber of Comerce
2025 Rogers Women of the Year Award Nominees
On behalf of the Greater KW Chamber of Commerce, we want to congratulate our 57 Members who were recognized as nominees for the 2025 Rogers Women of the Year Awards.
Congratulations to…
Arts & Culture
Carin Lowerison – GLA Theatre Company
Pam Patel – MT Space
Entrepreneur
(40+*)
Aura Hertzog – City of Kitchener
Kristy Miller – The Scented Market
Ainsley Poirier-Craig – Harp & Fin/ HF Events
Angel Marie Reiner – Onyx Condo Management
Lifetime Achievement
Jan Basso – Wilfrid Laurier University
Brenna Bonn – Waterloo Region Police Services
Charmaine Dean – University of Waterloo
Joan Fisk – CEO of United Way Waterloo Region Communities
Angie Hill – CTV
JoAnne McCormick – K-W Oktoberfest
Cathy Snyder – Nopak Canada Inc
Tracy Valko – Valko Financial LTD.
Skilled Trades
Stefanie Bruinsma – AutoCate
Emily Pyke – AutoCate
Community Service
Asma AlWahsh – Canadian Arab Women’s Association (CAWA)
Joan Fisk – United Way Waterloo Region Communities
Angie Hill – Bell Media Inc.
Jennifer Peacock – Habitat For Humanity Waterloo Region Inc
Stephanie Soulis – Little mushroom catering
Tracy Valko – Valko Financial
Group Achievement
Shelter Movers Southwestern Ontario
YW Club 84 – YWCA Kitchener Waterloo
She Shares Women’s Giving Circle – St. Mary’s General Hospital Foundation
She Is Your Neighbour – Women’s Crisis Services of Waterloo Region
Professional
(40+*)
Brenna Bonn – Waterloo Regional Police Service
Jennifer Gruber – Communitech
Ashley Howat – Waterloo Regional Health Network (WRHN)
JoAnne McCormick – K-W Oktoberfest Inc
Rebecca Schoenhardt – Canadian Western Bank
Cathy Snyder – Nopak Canada Inc
Carolina Soares – The Event Firm Inc.
Geraldine Stafford – Waterloo Regional Police Service
Kim Wilhelm – The Food Bank of Waterloo Region
STEM
Martha Breithaupt – BDO Canada LLP
Avvey Peters – NorthGuide
Kimberly Hebeisen – Mind Model AI
Charmaine Dean – University of Waterloo
Educator
*New for 2025*
Jan Basso – Wilfrid Laurier University
Lili Liu – University of Waterloo
Laura Matheson – Conestoga College
Tham Nguyen – Smartizen Canada Inc
Camelia Nunez – University of Waterloo
Health & Wellness
Chioma Efejedia – Inner Compass Wellbeing
Julie Norcott – Arise Wellness
Erin Seaton – Embark Physical Therapy
Rising Star (Under 40)
*New for 2025*
Christine Clark – Rogers
Erin D’Alessandro – Waterloo EDC
Shannon Hall – St. Jacobs Farmers Market
Faune Lang – Food4Kids
Mikaela Lewis – Remix Swing
Rebecca Lyons – Exera Solutions Inc.
Alicia Stuart – Harris Law Personal Injury Lawyers PC
Rochelle Williams – The Dessert Artist
Sanum Yousaf – Grazing Daisy
Young Adult (14-23)
Zoe Channer – Grand River Hospital Foundation
For full details on all of the nominees, please visit: womenoftheyear.ca/
The post 2025 Rogers Women of the Year Award Nominees appeared first on Greater KW Chamber of Commerce.
Cordial Catholic, K Albert Little
Does the Catholic Church Believe in Literal, Biblical Creation? (w/ Hugh Owen)
Greater Kitchener Waterloo Chamber of Comerce
HOW KW BUSINESSES CAN NAVIGATE ECONOMIC UNCERTAINTY THROUGH Disability Inclusion
April 2025
This time last year, an EV manufacturer in Kitchener was ramping up hiring for a new production line. Today, with input costs rising, trade tensions in flux, and demand becoming less predictable, their focus has shifted from growth to adaptability.
They’re not alone.
Across Kitchener-Waterloo, many businesses are navigating a new reality. Some are cautiously expanding, while others are doing more with less. But no matter where they are, they’re asking the same question: How do we build teams that can weather uncertainty and succeed in the long term?
Why Business Adaptability Matters in 2025Ontario’s job market is tightening. In March 2025 alone, the province lost 27,500 jobs, and unemployment rose to 7.5% (Statistics Canada, April 2025). While job seekers are feeling the pressure, many employers are too. Staffing remains a challenge, especially in sectors like manufacturing, healthcare, and skilled trades, which are core to Kitchener-Waterloo’s economy.
At the same time, retaining skilled team members is more critical than ever. Replacing an employee can cost up to 33% of their annual salary, according to the Work Institute’s 2023 Retention Report. High turnover drains time, productivity, and morale which is something businesses do not have the capacity to manage right now.
So, what can employers do to become more resilient?
How Disability Inclusion Can Support ChangeResearch from Accenture shows that companies prioritizing disability inclusion grow sales 2.9x faster and profits 4.1x faster than their competitors (Accenture, 2020). These companies tend to outperform because they build stronger, more adaptable teams.
Disability inclusive businesses are more likely to:
- Retain talent through inclusive culture and accessible practices
- Expand their talent pool
- Build psychological safety and trust across teams
- Improve innovation through diverse perspectives
In short: disability inclusion is good for business.
So, whether you’re expanding or stabilizing, these three strategies can help strengthen your business:
- Invest in Inclusive Workplace Culture
Retention starts with belonging. When team members feel supported, seen, and safe to be themselves, they are more likely to stay. Inclusive practices such as flexible onboarding and open communication can reduce turnover and increase engagement.
- Rethink Hiring Through a Skills-Based Lens
If you’re hiring, focus on creating accessible job postings that focus on skills and adaptability. This opens the door to talent who may have been overlooked through traditional hiring channels.
- Build Disability Confidence at All Levels
Most teams want to be disability inclusive but don’t always know where to start. That’s where practical training and support come in. Disability awareness and confidence training helps hiring managers, supervisors, and coworkers feel more equipped to support diverse teams, leading to better retention outcomes.
How OCTC Can HelpThe Ontario Corporate Training Centre (OCTC) is a province-wide project designed to support businesses across Ontario through research informed training, resources, and services.
Supported by the Ontario Disability Employment Network (ODEN) and funded by the Government of Canada, this project provides training and services at no cost for businesses within the manufacturing, skilled trades, healthcare and hospitality sectors. To learn more about Ontario Corporate Training Centre (OCTC) please visit www.ontariotrainingcentre.com.
What Comes NextWorkforce retention doesn’t happen overnight. It’s built through every decision of who you hire, how you support your team, and the values you bring into your workplace.
As economic pressures continue, disability inclusive hiring and retention practices are a strategic investment in your business’s future.
And the best part? You don’t have to do it alone.
If you would like to start or continue your inclusion journey, e-mail us at info@ontariotrainingcentre.com.
The post HOW KW BUSINESSES CAN NAVIGATE ECONOMIC UNCERTAINTY THROUGH Disability Inclusion appeared first on Greater KW Chamber of Commerce.
Elmira Advocate
WHAT IS MORE STUPID: LANXESS & GHD REFUSING TO BELIEVE TOPOGRAPHICAL ELEVATION CONTOUR LINES OR TRAC MEMBERS (less one) ALLOWING THEMSELVES TO BE BLUFFED BY THEM?
How is it possible especially when the majority of elevation contour lines have been provided by Conestoga Rovers and Associates? The rest have come from the Region of Waterloo, GRCA and the Ministry of Environment. Furthermore to date I have seen zero contradictions between any of the sources. Perhaps if Uniroyal Chemical had not perched their uncovered pits and ponds right at the highest elevations between the two properties then so much liquid toxins could not have moved eastwards onto the neighbouring Stroh Farm.
Contour lines do not lie. They are the elevation of the ground's surface above sea level. Despite this Luis Almeida and Lanxess have decided to go all in. I expected reticence on their part. Their history as well as that of their corporate predecessors has generally been abysmal when discussing transparency and honest discussion. What I find now is a corporate decision that can not be justified either in the short or long term. Their refusal to admit that their liquid wastes flowed more than a few metres onto the Stroh property is shockingly self-serving and shockingly glaringly bad.
I have recently reexamined those elevation contour lines. Yes some of the older maps are done in feet above sea level versus more recent ones done in metres above sea level (i.e. masl). Does Lanxess and GHD believe that TRAC members aren't smart enough to be able to convert feet to metres or do they think that TRAC members are too lazy or just don't care? This is what I have to observe carefully now. Why is only one TRAC member (Sebastian) pushing this while all the others appear to ignore it? Have many TRAC members been given their marching orders either from Lanxess or Woolwich Township and they don't want to rock the boat? Or is it just too much work as volunteers to look up these maps and see for yourselves?
This alleged Stroh "investigation" is equal in quality to others that the polluter and corporate successors have done over the decades.
Capacity Canada
Black Healing Centre
The Black Healing Centre (BHC) aims to design intergenerational programming that reimagines healing from a community-centered, artistic lens.
By providing access to free and subsidized therapy to members of the community, we seek to counteract the shared trauma that often comes with the Black experience, and empower people of African and Caribbean descent in Tiohtià:ke (Montreal) to reclaim their mental, physical, emotional, and spiritual wellness.
Our Mission:Black Healing Centre’s (BHC) goal is to provide an accessible space for intergenerational, culturally relevant, and afro-positive mental health care. BHC’s core mission is to create an accessible and safer space for Black people to gather, connect and heal.
Our intention is to create an Anti-oppressive, Anti-racist community hub where people of African descent feel seen, heard and supported. Our promise is to create an intentional space for us by us.
We simply want to foster an environment where people of African descent feel a sense of belonging, and do not have to explain, diminish, or defend their experiences.
You can learn more about the Black Healing Centre here: www.blackhealingcentre.com/
Join our Board of DirectorsAre you passionate about advancing access to wellness programs and spaces for Black people in Montreal? Do you have experience in fundraising, financial management, people operations management (HR), and/or strategy?
If so, we invite you to apply to join the Board of Directors of the Black Healing Centre. It’s an exciting time to join our board! We have recently secured a new physical space to conduct our in-person programming, and we have done some work to identify our
strategic priorities for the next 3 years. You will have the opportunity to work alongside a small and passionate team, sharing your skills and knowledge, and experience to help us ensure the long-term sustainability of our organization and deepen our impact.
We are looking to recruit new Board members to fulfill one of the following roles: Vice-Chair (1) & Director at large (2) . To learn more about what the different roles entails click here). We are especially interested in folks who align with our values and have experience in fundraising, finance, and/or nonprofit operations.
If you are ready to take on this rewarding and challenging role, we invite you to apply to join the Board of Directors of the Black Healing Centre today.
About the Commitment- Lengths of Involvement: A Board Member commits to serve a one-year term (for member at large position) or 2-year term for chair, vice-chair, treasurer, & secretary roles. Terms can be renewed.
- Time commitment: 10 – 15 hours per month. Board meetings are held monthly and virtually on Zoom the 2nd Tuesday in the evening. Committee meetings frequency may vary depending on the committee.
This is a really great opportunity if you:
- Have a passion to create wellness and care offerings for Black community members and Black mental health practitioners in Montreal (or beyond)
- Have the availability, and ability to attend board meetings and engage in committee work (fundraising, finance, etc.)
- Have strong communication and collaborative skills
Interested, but still unsure if you’re ready to serve on a board? This article by Evenings + Weekends Consulting is a great resource!
Interview & Selection ProcessPlease submit your application through our portal here. You will be asked to submit the following:
- Your Bio (one or two paragraphs)
- Your Letter/Video of interest includes:
- What inspires you to join our Board of Directors?
- The relevant experience and/or skills that you feel you can contribute to the Black Healing Centre
- Your availability to participate in Board meetings and committee meetings
- Which Board committee you would be interested in joining (at least): Programming, Governance, External, Space
- The deadline to apply is Tuesday May 13 at 10am ET
- Virtual interviews via Zoom will be scheduled between Thursday May 22, and Tuesday May 27 with the shortlisted candidates. Each interview will be expected to take 45 minutes
- Shortlisted candidates will receive a calendar invitation with the Zoom link as well as the interview questions (at least 48 hours ahead of their interview)
- If you require accommodation during any stage of the recruitment process, please notify Laëtitia Eyssartel at laetitia@eveningsandweekendsconsulting.com
Board Flyer
The post Black Healing Centre appeared first on Capacity Canada.
Greater Kitchener Waterloo Chamber of Comerce
Non-Profit/Charitable Award Winner: The KW Humane Society
On Thursday, March 20, 2025, the Greater Kitchener Waterloo Chamber of Commerce hosted the 2025 Business Excellence Awards Gala, presented by Cowan Insurance Group. The Waterloo Region business community, local dignitaries, and community ambassadors came together to honour the extraordinary contributions of more than 130 nominees across 14 categories.
Congratulations to the Humane Society of Kitchener Waterloo & Stratford Perth for taking home the Non-Profit/Charitable award! The KW Chamber dedicates this award to the business that truly supports the community in their day-to-day efforts, and uses what funding they receive to pour it back into causes that need it the most across Waterloo Region & beyond.
♦
With two community animal care centres in Kitchener-Waterloo and Stratford, Ontario, The Humane Society of Kitchener Waterloo & Stratford Perth supports over 500,000 people across 13 municipalities. Self-funded and self-governed, they are a recognized leader in animal welfare.
In the past year, The Humane Society has made significant strides in both animal welfare and community support. Programs like their Pet Pantry have provided essential pet food and supplies to families experiencing financial hardship. In 2024, their Humane Education Programs reached over 21,000 students, fostering compassion and responsibility toward animals in future generations. Plus, the organization delivered over $30,000 worth of free veterinary services through their Veterinary Outreach efforts, assisting 269 pets in need. Their mission goes beyond animal care—they are deeply dedicated to creating a compassionate, supportive community for both animals and people.
Innovation is at the heart of The Humane Society’s work. Their successful Better Together Capital Campaign, which raised an impressive $362,000, included a Taylor Swift concert ticket giveaway and marked the organization’s most successful fundraiser to date. These funds will be used to develop a new Community Outreach Centre, designed to provide more accessible services for both animals and people.
Through these initiatives, The Humane Society of Kitchener-Waterloo Stratford Perth has not only transformed the lives of countless animals but also strengthened the fabric of the community.
The post Non-Profit/Charitable Award Winner: The KW Humane Society appeared first on Greater KW Chamber of Commerce.
Cordial Catholic, K Albert Little
The saints can pray for us. #bible #catholicchurch #apologetics #christian #church
Code Like a Girl
My Teen’s Instagram Account was Hacked
♦
What happened, how it happened, and how to protect your kid from the same fate.
Continue reading on Code Like A Girl »
Adam Wathan
Building a Slide-Over Panel with Tailwind CSS
James Davis Nicoll
Maybe Make Believe / Correspondence By Sue Thomas
Sue Thomas’ 1992 Correspondence is a stand-alone science fiction novel.
All of the modern world’s wonders cannot protect one from loss and grief. A single moment can erase spouse and children. However, those wonders do offer a solution.
Two solutions, in fact.
…
Brickhouse Guitars
Boucher HG-56-BIM #IN-1310-12FTB Demo by Roger Schmidt
Bardish Chagger
Re-Elect Bardish Chagger - A Strong Voice For Waterloo
Brickhouse Guitars
Boucher BG42T-G #MYT-1014-DB Demo by Roger Schmidt
Kitchener-Waterloo House League Baseball
2025 Coaches Meetings
The 2025 Coaches Meetings were held the week of April 22, 2025. If you missed the meeting, you can view the slides here (top right corner). Don't hesitate to reach out to your convenor with any questions.
Github: Brent Litner
brentlintner pushed to master in brentlintner/vim-settings
-
♦
698b935
Update packages
Code Like a Girl
Here’s How I’d Prepare for a Tech Interview Today
Back when I was preparing for my first tech job, I thought interviews were this big scary thing. I watched 20+ YouTube videos, bookmarked every roadmap, tried to do 100 LeetCode questions in a week… and still felt unprepared.
Today, I interviewed a candidate for a fresher role. And I realize — most of you are still confused the same way I was. So let’s clear the air.
Here’s exactly what you should focus on. And equally, what you can ignore (at least for now).
What Interviewers Actually Look ForLet’s start with the truth. For fresher roles, companies don’t expect you to build a distributed system or know the internals of a compiler.
Companies are mainly looking for five things:
- Clear thinking — Can you break down a problem step-by-step?
- Strong basics — Arrays, loops, strings, functions. That’s it.
- Some hands-on exposure — Projects or internships, even tiny ones.
- A curious attitude — Are you eager to learn? Can you take feedback?
That’s it. No trick. No secret.
DSA — It’s Important, But Don’t Get LostYes, you need to know basic Data Structures and Algorithms. But that doesn’t mean memorizing 300 questions or panicking over Dynamic Programming.
Start small and go deep:
- Arrays, Strings, HashMaps
- Sorting & Searching
- Recursion & Basic Trees
A candidate who can explain how a HashMap works and use it in a basic problem often performs better than someone who blindly solves advanced questions.
Pro tip: Solve fewer problems, but understand why they work.
Projects — Your Best (and Most Underrated) AssetA solid personal project can speak louder than any DSA question.
interviewer love asking:
- Why did you build this?
- What problems did you face?
- How did you fix them?
You don’t need to make the next unicorn startup. It’s not about scale. Even a simple weather app or portfolio site shows initiative. What matters is whether you understand your code and can talk about it.
Pro tip: Share the GitHub link, include a README, maybe even a demo. Add a screenshot. It shows effort. It shows interest. That’s what we care about.
Talk to the interviewer, Not Just the KeyboardThis is such a big one. I’ve seen brilliant coders fail interviews because they stayed silent while thinking.
interviewer not mind readers.
Say things like:
- “Okay, I’m thinking of using a hash map here…”
- “Let me walk you through my logic.”
- “I’m not sure about the syntax, but I’d Google this…”
This tells that you’re structured, thoughtful, and collaborative.
Silence = uncertainty. Speech = confidence.
Where Most Freshers Go WrongLet’s clear some confusion. Here’s what not to do:
- Overpreparing random stuff: You don’t need to learn system design, Kubernetes, and blockchain all at once. Stick to the basics.
- Blindly following roadmaps: Everyone’s journey is different. Don’t try to tick off every topic you see on LinkedIn.
- Faking projects: We can tell when you haven’t written the code yourself.
- Giving up too early: You don’t need to get everything right. You just need to show potential.
Here’s a simple plan I recommend to freshers:
- Pick one language (JavaScript, Python, Java — anything you’re comfortable with)
- Practice 1–2 DSA problems daily from easy-level sets (NeetCode, Striver, GFG)
- Build 1–2 small projects you genuinely enjoyed making
- Learn how to talk about your code — in your resume and during interviews
- Do 2–3 mock interviews with friends, online platforms, or mentors
That’s it. No need for 10 resources. Just pick a few and go deep.
What Actually Stands Out in an InterviewHere’s what often impresses interviewers — even more than a right answer:
- Clean, readable code with good variable names
- Thinking out loud and being transparent with your logic
- Admitting when you’re unsure, and then making progress anyway
- Talking about a project you built just because you wanted to
- Asking questions that show curiosity (e.g., “Could I have done this differently?”)
Freshers who show potential, enthusiasm, and willingness to learn often get further than those chasing perfection.
Final Thoughts: You Don’t Need to Know EverythingTo every fresher reading this: perfection is not the expectation. Interviewers understand that candidates are just starting out — and they’re assessed accordingly.
Interviewers aren’t looking for a walking textbook. What truly stands out is:
- Clear thinking
- Honest communication
- A curious mindset
So the next time an interview comes around, there’s no need to impress with everything under the sun. Instead, focus on showing how you approach problems, what you’ve built, and why it matters to you.
Bonus Resources (Only If You Need Them)- TakeUForward
- Frontend Mentor / Backend Projects
- Mock Interviews — Pramp / Interviewing.io
Here’s How I’d Prepare for a Tech Interview Today was originally published in Code Like A Girl on Medium, where people are continuing the conversation by highlighting and responding to this story.
Code Like a Girl
How to Raise Concerns at Work
♦
When you put aside issues that matter and don’t put in the effort to get them resolved, they keep consuming your mental bandwidth and…
Continue reading on Code Like A Girl »
Greater Kitchener Waterloo Chamber of Comerce
Environment & Sustainability Award Winner: Waterloo Wellington Flight Centre
On Thursday, March 20, 2025, the Greater Kitchener Waterloo Chamber of Commerce hosted the 2025 Business Excellence Awards Gala, presented by Cowan Insurance Group. The Waterloo Region business community, local dignitaries, and community ambassadors came together to honour the extraordinary contributions of more than 130 nominees across 14 categories.
Congratulations to the Waterloo Wellington Flight Centre for winning the 2025 Environment & Sustainability award! This honour is dedicated to the business that puts the environment at the forefront of their priorities and ensuring that sustainable practices are involved throughout their workplace.
♦
Waterloo Wellington Flight Centre has become a leader, locally and globally, in integrating sustainability into the aviation industry. The center has embraced eco-friendly practices and made groundbreaking strides toward reducing its carbon footprint. In 2023, Waterloo Wellington Flight Centre made history by introducing Canada’s first electric training aircraft, significantly reducing carbon emissions associated with traditional aviation training. This aircraft has already completed over 100 test flights and has the potential to revolutionize flight training, providing a more sustainable alternative to fossil-fuel-based aircraft.
Last year, the expansion of Hangar 7 reflects their dedication to sustainable infrastructure. The 10,000-square-foot addition features solar power, an energy-efficient HVAC system, and improved insulation. The installation of a solar energy system at Hangar 7 is expected to reduce CO2 emissions by approximately 18.39 tonnes annually and generate around 47,000 kWh of energy each year, making it a model for green building practices in the aviation sector. Plus, their partnership with the University of Waterloo will accelerate the adoption of green technologies and develop the next generation of sustainable aviation practices.
The post Environment & Sustainability Award Winner: Waterloo Wellington Flight Centre appeared first on Greater KW Chamber of Commerce.
Code Like a Girl
Top 10 Ways to Protect Your MERN Application Like a Pro
♦
A comprehensive beginner-friendly guide on securing the MERN apps from vulnerabilities and attacks
Continue reading on Code Like A Girl »
Adam Wathan
Exploring the Tailwind CSS v4.0 Beta with Sam Selikoff
Elmira Advocate
TRAC ARE WAY PAST OVERDUE TO WALK AWAY
No criteria. No red line. No benchmark. Mostly nothing except perhaps history to show citizens, the public and TRAC members how much pumping is absolutely required to keep Uniroyal Chemical's contaminants from flowing off-site via groundwater. GHD and Lanxess mutter about circumstances and varying conditions. They suggest that it takes several geniuses plus a pinch of fairy dust in order to determine the amount of on-site pumping required in the Municipal Upper Aquifer to contain their site.
Bull**it says I ! All anybody has to do is assemble the on-site pumping data from the last three or four years and compare it to each month's off-site pumping. The two are related in that from the very beginning we were told that the vastly higher off-site pumping will challenge the on-site pumping by drawing down the off-site aquifer's elevations and tend to draw on-site groundwater off-site. It's all about the relationship between the two numbers.
In 2022 eight months exceeded 4.0 litres per second on-site pumping with the four months below 4.0 averaging 3.6 litres per second (l/sec).
The same year total off-site pumping exceeded 55 l/sec for eleven of the twelve months which is quite high historically
In 2023 four months met or exceeded 4.0 l/sec on-site pumping with the remaining eight months averaging 3.7 l/sec.
The same year total off-site pumping exceeded 55 l/sec for eight months and was between 24.6 and 55 l/sec for the rest.
In 2024 zero months exceeded 4.0 l/sec on-site pumping with twelve months averaging 3.4 l/sec.
The same year total off-site pumping exceeded 55 l/sec for five months with the remaining eight months averaging 37.4 l/sec.
To date in 2025 zero months met or exceeded 4.0 l/sec on-site pumping.
This year (Jan.-March) total off-site pumping has exceeded 55 l/sec. for two of the three months and the third month was at 41.1 l/sec.
The conclusions are obvious. Lanxess are reducing both on-site pumping dramatically the last four years at the same time that off-site pumping has also been reduced albeit less dramatically.
So are they intentionally wimping out on all pumping and treating to save on costs and or are they intentionally reducing on-site pumping more in order to drag contaminants off site that if treated will be treated partially at taxpayers' expense versus all their own expense?
Jesse Roders
What Builders Look For
TLDR; Builders don’t care about polish, programs, or pitches. They look for momentum, seriousness, aligned incentives, and honest friction. If the room isn’t real, they quietly leave.
There’s a quote — often attributed to Picasso — that goes: “When art critics get together, they talk about form and structure. When artists get together, they talk about where to get cheap turpentine.”
Melissa and Johnathan at Raw Signal Group reminded us of that quote in The Poser Manifesto, a piece that perfectly captures the difference between the people doing the thing and the people talking about the thing.
That line stuck with us. Because it’s how builders see the world, too.
When you’re in the thick of it — launching, fixing, iterating — you start filtering rooms differently. You stop looking for recognition and start scanning for something more useful: signs that this place, this group, this conversation, might help you build.
Builders look for momentum, not programmingIf the room is full of pitch decks but nobody’s shipped anything in the last six months, we’re already thinking about the door. Builders don’t need more frameworks or panels. We need speed, traction, and someone who’s been there.
Momentum is everything. Without it, the conversation is just noise. With it, everything else becomes easier.
Builders look for seriousness, not polishYou don’t need a Stanford MBA to earn respect in a builder room. You don’t need the perfect branding or the right pitch cadence. You just need to be in the work. Not someday. Not eventually. Right now.
We respect obsession. We recognize commitment. We are less interested in how something looks than in what it does — and whether you’re willing to keep going when it gets hard.
Builders look for aligned incentivesWe always check who’s funding the work. Builders are excellent at following the money. We know when something is optimized for government grants instead of founder success. We know when the real client is a sponsor, not the founder or builder in the room.
It’s not subtle. And it changes everything about how a room operates.
Builders look for honest frictionBuilding is hard. Good rooms don’t avoid tension — they surface it and move through it. Conflict is not a problem. Avoiding it is.
If no one’s asking hard questions, no one’s doing hard things. And if everyone in the room is nodding politely, we’re probably not learning anything new.
Builders look for who’s still showing upThe sharpest builders don’t leave loudly. They just stop showing up. And when that happens, we notice. You can learn a lot about a room by who left quietly and never came back.
Founders and builders have limited time. If they’re not in the room, there’s probably a reason.
What to do with thisBuilders aren’t precious. We don’t need special treatment. But we notice what’s real. We notice who’s working. We notice where the momentum is.
If you want to support builders, don’t tell us. Build the kind of room we’ll want to be in.
We’ll know.
We’re just busy finding turpentine.
Check out builder lead events here and join us at the Builders Club.
♦What Builders Look For was originally published in Who You Calling a Jesse? on Medium, where people are continuing the conversation by highlighting and responding to this story.
KW Habilitation
April 23, 2025: What’s Happening in Your Neighbourhood?
♦Coffee Conversation and Lunch
Tuesday, April 29
11:30 AM – 1:00 PM
FREE – Registration Required
Mill-Courtland Community Centre – 216 Mill St. Kitchener
Break bread with neighbours, meet friends, and have great conversations! At this peer-led group, participants are served a healthy lunch while they get to know each other. A take-out lunch is also available for participants who prefer that format. Call the Mill-Courtland Community Centre at 519-741-2491 to register.
Click here for more info
♦Tranquil Yoga
Wednesday April 23, 30 and May 7
6:15 PM – 7:15 PM
FREE
Langs – 1145 Concession St. Cambridge Room E123
Join us for a calming and empowering yoga experience designed exclusively for women age 18 years or older. Tranquil Yoga offers a safe and welcoming space to unwind, stretch, and reconnect with yourself. Take a break midweek to find your peace and strength. No experience needed – all levels welcome! We recommend participants be here for 6:00PM for registration, so you can enjoy the full time of the session.
Click here for more info
♦Wonderfully Made Spring Market
Saturday, May 3
10:00 AM – 3:00 PM
FREE
Catalyst 137 – 137 Glasgow St. Kitchener
Discover one-of-a-kind gifts and meet the makers who bring them to life! Come out to Catalyst 137 and shop from a curated selection of 50 makers and talented artisans in Waterloo Region. Make us your Mother’s Day shopping destination with hundreds of handcrafted, one-of-a-kind locally grown products and unique gifts! Stock up on hostess gifts, tasty treats, teacher gifts, or buy a little something for yourself. There is something for everyone at the Spring Market. Free swag bags to the first 50 guests!
Click here for more info
♦
Election Day♦
Monday, April 28
9:30 AM – 9:30 PM
FREE
Find your Polling Centre here
The 2025 Canadian Federal Election is today. If you need assistance voting. Don’t forget to bring the correct paperwork to verify your identity and address. Learn more what papers to bring here. Get out there and may your vote count.
Click here for more info
Connection Café
Wednesday, April 30
10:00 AM – 11:00 AM
FREE
Health Caring KW – 44 Francis St. S, Kitchener
The Connection Café is a relaxed space where community members gather to enjoy coffee or tea and connect with others. Led by peers, it’s all about making social connections and fostering a sense of belonging.
Click here for more info
Singalong With Kento
Wednesdays
April 30 to June 11
1:30 PM – 3:30 PM
FREE
Trillium Lutheran Church – 22 Willow St. Waterloo
It’s that time of year again! Come and enjoy the musical leadership of Kento Stratford at our Wednesday afternoon sing-alongs. Come and sing or just listen to the music. Each week is a unique combination of songs from the 1940s-1990s. Refreshments provided during break. This is a free, all-ages event.
Click here for more info
Guided Nature Walk – Strasburg Woods
Friday, May 2
10:00 AM – 11:30 AM
FREE
Trail Entrance – Rush Meadow St. and Anson Ct. Kitchener
Explore one of Kitchener’s natural areas on this guided walk. There will be time to enjoy the sights and sounds, take photos, and indulge our curiosities about nature. Please dress for the weather and trail conditions. Note: Washroom facilities are not available at this location.
Click here for more info
Mannheim Community Garage Sale and Optimist BBQ
Saturday, May 3
7:30 AM – 1:00 PM
FREE Admission
Mannheim Community Centre – 1467 Mannheim Rd. Wilmot
This year, we’re excited to host the BBQ at a new location—the Mannheim Community Centre and Park. The new venue offers parking and plenty of picnic benches, making it a perfect spot to enjoy your meal. Bacon burgers, sausages, veggie sausages, hot dogs and refreshments will be available for purchase. All proceeds from the BBQ go to the Optimist Club of Mannheim to support events and programs for children in our community. Lots of houses will be having garage sales all throughout the neighbourhood during this day as well.
Click here for more info
♦
Open Space: Games & Social Drop-In
Mondays
6:30 PM – 8:00 PM
FREE
Central Library – 85 Queen St. N, Kitchener
Open Space is a weekly gathering that promotes inclusion within the community by getting people together for food, fun and conversation. All are encouraged and welcome regardless of ability, and you do not need to be supported by Extend-A-Family Waterloo Region to attend. Bring a friend and enjoy.
Click here for more info
Family Pow Wow Drum Night
Tuesdays
6:00 PM – 8:00m PM
FREE
Downtown Community Centre – 35 Weber St. S, Kitchener
The drum brings the heartbeat of Mother Earth for all to feel and hear. Drumming brings us back into balance. Connect with spirit whether dancing, singing or just listening. Come for community, to share stories, sing and dance, you do not have to sit at the drum to attend. You are welcome to bring your regalia for dancing. Every Tuesday!
Click here for more info
2SLGBTQIA+ Multi-Sport Drop-in
Saturdays
1:15 PM – 2:45 PM
FREE
Stanley Park Community Centre – 505 Franklin St, S, Kitchener
It’s the gym class you wish you had in high school! For ages 18+. Join us in the gym for basketball, volleyball, badminton, floor hockey, dodgeball and more! This will be a beginner friendly safe space for every BODY!
Click here for more info
The post April 23, 2025: What’s Happening in Your Neighbourhood? appeared first on KW Habilitation.
Code Like a Girl
Multithreading and Mutexes Made Simple
♦
When you run a program, what actually runs it?
Continue reading on Code Like A Girl »
Code Like a Girl
A Complete Guide to Build, Test and Deploy a Spring Boot Application
Dear Readers, this is one of the most frequently asked interview questions about Spring Boot. Some interviewers expect you to write the complete flow of client request, controller, service, repository and database.
They mainly check end-to-end flow and how well annotations are used.
Let's understand with an example how to start and run the Spring Boot application with a basic example.
♦Master SpringBoot ApplicationCreating the First Spring Boot ApplicationCreating an executable Spring Boot Application requires a few prerequisites.
- JDK(Java Developemnt Kit)
- Apache Maven
- Code editor
We will create an Employee Management application that uses an in-memory H2 database, implementing all CRUD operations.
In this example, I’ll be using Intellij IDEA community edition; you can also use any other editor of your choice.
You can install JDK using this article and Apache Maven from here.
Once we have the prerequisites settled, it's only a few steps towards your first Spring Boot application. Here’s what you need to do :
Step1: Installing Prerequisites1. 1 Installing Java and MavenInstalling Java (JDK 17+)Download the JDK from Oracle. Then set your environment variables:
export JAVA_HOME=/path/to/jdk1.2 Installing Maven
export PATH=$JAVA_HOME/bin:$PATH
java -version # Verify your installation
Download Maven from the Apache Maven website and verify with:
mvn -versionStep 2: Creating the Spring Boot Project via Spring Initializr
Go to Spring Initializr and configure your project as follows:
Enter your project metadata. This includes :
- The Group or Domain name under which you’re building your application. If you own a domain name or you’re working for a specific company, you can use their domain name here.
example: The domain name com.employees , if you don’t have a domain name, then you can just go with com.example.your_project_name. - The Artifact and Name of the project — The artifact and name is an identifiers for your Spring Boot application.
- The project Description.
- The Package Name, which will be auto-filled as you enter the details above.
- Add all the required dependencies.
- The Packaging — This decides if the application would be packaged as a JAR file or a WAR file. By default, we’ll go with the JAR file selection.
The last step is to select the Java version which will execute this project, we need to make sure that this is the version that is also installed in our system. We’ll go with Java 17 for this example.
Download the ZIP file, extract it and import it into your IDE.
- Project: Maven Project
- Language: Java
- Spring Boot: 3.1.1 (or the latest version)
- Group: com.employee
- Artifact: employee
- Dependencies:
- Spring Web
- Spring Data JPA
- H2 Database
- Spring Boot Starter Validation
- Lombok
- MapStruct
- Spring Boot Starter Test
After importing, your project should have a structure similar to:
employeeStep4. Implementing CRUD APIs
├── pom.xml
├── Dockerfile
├── deployment.yaml
└── src
├── main
│ ├── java/com/employee
│ │ ├── EmployeeApplication.java // Main class (@SpringBootApplication)
│ │ ├── controller
│ │ │ └── EmployeeController.java // REST endpoints (@RestController)
│ │ ├── service
│ │ │ └── EmployeeService.java // Business logic (@Service)
│ │ ├── repository
│ │ │ └── EmployeeRepository.java // DAO (@Repository)
│ │ ├── entity
│ │ │ └── Employee.java // JPA entity (@Entity)
│ │ ├── dto
│ │ │ └── EmployeeDto.java // Data Transfer Object (POJO with Lombok)
│ │ ├── mapper
│ │ │ └── EmployeeMapper.java // MapStruct mapper (@Mapper)
│ │ └── exception
│ │ ├── EmployeeException.java // Custom exception (@ResponseStatus)
│ │ └── GlobalExceptionHandler.java // Global exception handler (@ControllerAdvice)
│ └── resources
│ └── application.yml // App configuration (H2 settings)
└── test
├── java
│ ├── com/employee
│ ├── integration/controller
│ │ └──EmployeeControllerTest.java // Controller integration tests (@WebMvcTest)
│ │
│ ├── service
│ │ └──EmployeeServiceTest.java // Service integration tests (@SpringBootTest, @ExtendWith)
│ ├──. TestDataFactory.java // Utility class for test data
│
└── resources
└── application.yml // Test-specific configuration (e.g., H2 settings)
Let’s build the core application first.
4.1 Main Application ClassEmployeeApplication.java
@SpringBootApplication
public class EmployeeApplication {
public static void main(String[] args) {
SpringApplication.run(EmployeeApplication.class, args);
}
}
- @SpringBootApplication: Combines configuration, auto-configuration, and component scanning. It tells Spring Boot where to start.
Handles HTTP requests and responses, acting as the entry point for the API.
EmployeeController.java
package com.employee.controller;
import com.employee.common.mapper.EmployeeMapper;
import com.employee.common.utils.ControllerUtils;
import com.employee.dao.Employee;
import com.employee.dto.EmployeeDto;
import com.employee.response.EmployeeResponse;
import com.employee.service.EmployeeService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(path = "/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@Resource
private EmployeeMapper employeeMapper;
// GET API
@GetMapping
public ResponseEntity<EmployeeResponse<Employee>> getAllEmployees(
@RequestParam(defaultValue = "0") int offset,
@RequestParam(defaultValue = "10") int pageSize,
@RequestParam(defaultValue = "id") String sortBy,
@RequestParam(defaultValue = "ASC") Direction dir
) {
return ControllerUtils.buildOkResponse(
employeeService.findTeamWithPagination(offset, pageSize, sortBy, dir));
}
// GET API
@GetMapping("/{id}")
public ResponseEntity
<Employee> getEmployeeById(@PathVariable Long id) {
Employee employee = employeeService.findEmployeeById(id);
if (employee != null) {
return ResponseEntity.status(HttpStatus.OK).body(employee);
} else {
System.out.println("Not Found");
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
}
// CREATE API
@PostMapping
public ResponseEntity<Employee> saveEmployee(@Valid @RequestBody EmployeeDto employeeDto) {
System.out.println(employeeDto);
return ResponseEntity.status(HttpStatus.CREATED).body(employeeService.saveEmployee(employeeDto));
}
// DELETE API
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteEmployee(@PathVariable Long id) {
employeeService.deleteEmployeeById(id);
return ResponseEntity.noContent().build();
}
// PUT API
@PutMapping("/{id}")
public ResponseEntity<Employee> updateEmployee(
@PathVariable Long id,
@RequestBody EmployeeDto employeeDto) {
Employee updatedEmployee = employeeService.updateEmployee(id, employeeDto);
if (updatedEmployee != null) {
return ResponseEntity.ok(updatedEmployee);
} else {
return ResponseEntity.notFound().build();
}
}
}
Annotations explained:
- @RestController: Declares that the class handles REST calls, and responses are automatically serialized to JSON.
- @RequestMapping: Defines a base URI for the controller.
- @PostMapping, @GetMapping, @PutMapping, @DeleteMapping: Shortcut annotations to map HTTP methods.
- @RequestBody: Converts JSON from the request into the corresponding DTO.
- @PathVariable: Binds URI variables to method parameters.
- @Valid: Used to enforce validation on request body objects
Contains business logic and interacts with repositories.
EmployeeService.java
package com.employee.service;
import com.employee.common.mapper.EmployeeMapper;
import com.employee.dao.Employee;
import com.employee.dto.EmployeeDto;
import com.employee.exception.EmployeeException;
import com.employee.repository.EmployeeRepository;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.util.Map;
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
@Resource
private EmployeeMapper employeeMapper;
public void test() {
System.out.println("tets");
}
public Employee getEmployee(Long id) {
return employeeRepository.findById(id)
.orElseThrow(() -> new EmployeeException("Employee not found with id " + id));
}
public Employee saveEmployee(EmployeeDto employeeDto) {
return employeeRepository.save(employeeMapper.EmployeeDtoToDao(employeeDto));
}
public Page<Employee> findTeamWithPagination(final int offset, final int pageSize,
final String sortBy, final Sort.Direction dir) {
return employeeRepository.findAll(PageRequest.of(offset, pageSize, Sort.by(dir, sortBy)));
}
public Employee findEmployeeById(Long id) {
return employeeRepository.findById(id).orElseThrow(() -> new EmployeeException("Employee not found with id " + id));
}
public void deleteEmployeeById(Long id) {
employeeRepository.deleteById(id);
}
public Employee updateEmployee(Long id, EmployeeDto employeeDto) {
return employeeRepository.findById(id).map(existingEmployee -> {
// Map DTO to existing entity
employeeMapper.updateEmployeeFromDto(employeeDto, existingEmployee);
return employeeRepository.save(existingEmployee);
}).orElse(null);
}
}
Annotations explained:
- @Service: Marks the class as a service, making it eligible for component scanning.
- @Autowired: Injects dependencies automatically.
- @Resource: Used for dependency injection, typically to inject beans by name (default) or type.
EmployeeDto.java
package com.employee.dto;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.*;
import lombok.Builder;
import java.time.LocalDate;
import java.util.Date;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class EmployeeDto {
private Long id;
@NotBlank(message = "First name is required")
@Size(min = 2, max = 50, message = "First name must be between 2 and 50 characters")
private String firstName;
private String lastName;
@NotBlank(message = "Email is required")
@Pattern(regexp = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$", message = "Please provide a valid email address")
private String email;
@NotBlank(message = "Phone number is required")
@Pattern(regexp = "^\\+?[0-9]{7,15}$", message = "Phone number must be between 7 and 15 digits and can include a leading '+'")
private String phoneNo;
@NotBlank(message = "Job title is required")
@Size(max = 100, message = "Job title must not exceed 100 characters")
private String jobTitle;
@NotBlank(message = "Department is required")
@Size(max = 100, message = "Department must not exceed 100 characters")
private String department;
private LocalDate dateOfJoining;
@NotBlank(message = "Employment type is required")
@Pattern(regexp = "(Full-Time|Part-Time|Contract|Internship)",
message = "Employment type must be one of: Full-Time, Part-Time, Contract, Internship")
private String employmentType;
@NotBlank(message = "Emergency contact is required")
@Pattern(regexp = "^\\+?[0-9]{7,15}$", message = "Emergency contact number must be between 7 and 15 digits and can include a leading '+'")
private String emergencyContact;
}
Annotations explained:
- @Data: (Lombok) Auto-generates getters, setters, equals, hashCode, and toString.
- @Builder: Enables the builder pattern for easy object creation.
- @NoArgsConstructor / @AllArgsConstructor: Generate constructors with no arguments and with all properties.
- Please add necessary validation for the required fields.
Employee.java
package com.employee.dao;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDate;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "Employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String email;
private String phoneNo;
private String jobTitle;
private String department;
private LocalDate dateOfJoining;
private String employmentType;
private String emergencyContact;
}
Annotations explained:
- @Entity: Declares the class as a JPA entity.
- @Id and @GeneratedValue: Define the primary key and its generation strategy.
EmployeeRepository.java
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {}
Annotations explained:
- @Repository: Indicates that the interface is a data access component.
- JpaRepository: Provides CRUD operations and additional JPA functionalities.
EmployeeMapper.java
package com.employee.common.mapper;
import com.employee.dao.Employee;
import com.employee.dto.EmployeeDto;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
@Mapper(componentModel = "spring",
uses = {LocalDateMapper.class})
public interface EmployeeMapper {
EmployeeDto EmployeeDaoToDto(Employee employee);
Employee EmployeeDtoToDao(EmployeeDto EmployeeDto);
@Mapping(target = "id", ignore = true)
void updateEmployeeFromDto(EmployeeDto dto, @MappingTarget Employee employee);
}
Annotations explained:
- @Mapper: Tells MapStruct to generate the mapping code. The componentModel = "spring" option makes the mapper a Spring bean.
EmployeeException.java
package com.employee.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class EmployeeException extends RuntimeException {
public EmployeeException(final String msg) {
super(msg);
}
}
Annotations explained:
- @ResponseStatus: Specifies the HTTP status to return when the exception is thrown.
GlobalExceptionHandler.java
package com.employee.exception;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
/**
* Wraps all exceptions thrown during any integration call to teams APIs
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandling {
/**
* Wrap All MethodArgumentNotValidException Exception
*
* @param exception identifies unique contact
* @return ResponseEntity<Object>
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<Object> handleMethodArgumentNotValidException(
final MethodArgumentNotValidException exception) {
Map<String, String> errorMap = new HashMap<>();
exception.getBindingResult().getFieldErrors().forEach(error -> {
errorMap.put(error.getField(), error.getDefaultMessage());
});
return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST);
}
/**
* Wrap All TeamsApiException Exception
*
* @param exception identifies unique contact
* @return ResponseEntity<Object>
*/
//@ExceptionHandler(EmployeeException.class)
public final ResponseEntity<RestErrorResponse> handleEmployeeException(
final EmployeeException exception) {
log.error(exception.getMessage());
final RestErrorResponse errorResponse = new RestErrorResponse();
errorResponse.setTimestamp(Instant.now().toEpochMilli());
errorResponse.setMsg(exception.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
}
Annotations explained:
- @ControllerAdvice: Enables centralized exception handling across all controllers.
- @ExceptionHandler: Specifies which exception the method handles.
- @Slf4j: (Lombok) Provides a logger for logging errors.
In your src/main/resources/application.properties, configure H2:
spring.datasource.url=jdbc:h2:mem:employeedb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
This configuration:
- Creates an in-memory database named employeedb.
- Enables the H2 console (accessible at /h2-console) so you can view and test your data.
Our test suite is divided into multiple parts:
6.1 Test Data FactoryTestDataFactory.java
package com.employee;
import com.employee.dao.Employee;
import com.employee.dto.EmployeeDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class TestDataFactory {
public static EmployeeDto buildTestEmployeeDtoWithMinimalData() {
return EmployeeDto.builder()
.firstName("John")
.lastName("Doe")
.build();
}
public static EmployeeDto buildTestEmployeeDtoWithFullData() {
return EmployeeDto.builder()
.id(1L)
.firstName("Jane")
.lastName("Smith")
.email("jane.smith@example.com")
.phoneNo("+1234567890")
.jobTitle("Software Engineer")
.department("IT")
.dateOfJoining(LocalDate.now())
.employmentType("Full-Time")
.emergencyContact("+9876543210")
.build();
}
public static Employee buildTestEmployeeDao() {
return Employee.builder()
.id(1L)
.firstName("John")
.lastName("Doe")
.email("john.doe@example.com")
.phoneNo("+1234567890")
.jobTitle("Developer")
.department("Engineering")
.dateOfJoining(LocalDate.now())
.employmentType("Full-Time")
.emergencyContact("+9876543210")
.build();
}
public static Page<Employee> buildTestEmployeeDaoWithPaging() {
List<Employee> employees = new ArrayList<>();
employees.add(buildTestEmployeeDao());
final PageRequest pageable = PageRequest.of(0, 1);
return new PageImpl<>(employees, pageable, employees.size());
}
}
Explanation:
- This class is a utility for creating test data. It provides methods to create DTOs and DAO objects (entities) and even paginated results.
- It keeps tests DRY and helps maintain consistency across test cases.
EmployeeControllerTest.java
package com.employee.integration.controller;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import com.employee.TestDataFactory;
import com.employee.dao.Employee;
import com.employee.dto.EmployeeDto;
import com.employee.response.EmployeeResponse;
import com.employee.service.EmployeeService;
import com.fasterxml.jackson.databind.ObjectMapper;
import static org.hamcrest.core.StringContains.containsString;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@SpringBootTest
@AutoConfigureMockMvc
class EmployeeControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private EmployeeService employeeService;
@Autowired
private ObjectMapper objectMapper;
private EmployeeDto validEmployeeDto;
private Employee existingEmployee;
@BeforeEach
void setUp() {
validEmployeeDto = TestDataFactory.buildTestEmployeeDtoWithFullData();
existingEmployee = employeeService.saveEmployee(validEmployeeDto);
}
@Test
void getAllEmployees_ShouldReturnPaginatedResults() throws Exception {
// Create test data
for (int i = 0; i < 15; i++) {
EmployeeDto dto = TestDataFactory.buildTestEmployeeDtoWithFullData();
dto.setFirstName("Employee-" + i);
dto.setEmail("employee" + i + "@example.com");
employeeService.saveEmployee(dto);
}
// Test pagination parameters
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/employees")
.param("offset", "1")
.param("pageSize", "5")
.param("sortBy", "firstName")
.param("dir", "ASC")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
EmployeeResponse<Employee> response = objectMapper.readValue(
result.getResponse().getContentAsString(),
new com.fasterxml.jackson.core.type.TypeReference<>() {
});
assertThat(response.getData()).hasSize(5);
assertThat(response.getPagination().getPage()).isEqualTo(1);
assertThat(response.getPagination().getTotalPages()).isEqualTo(5); // 16 total / 5 per page
assertThat(response.getData().get(0).getFirstName()).startsWith("Employee-");
}
@Test
void getEmployeeById_ShouldReturnEmployeeWhenExists() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/employees/{id}", existingEmployee.getId())
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(existingEmployee.getId()))
.andExpect(jsonPath("$.firstName").value(validEmployeeDto.getFirstName()));
}
@Test
void getEmployeeById_ShouldReturn404WhenNotFound() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/employees/9999")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound());
}
@Test
void createEmployee_ShouldReturnCreatedEmployee() throws Exception {
EmployeeDto newEmployee = TestDataFactory.buildTestEmployeeDtoWithFullData();
newEmployee.setEmail("new.employee@example.com");
mockMvc.perform(MockMvcRequestBuilders.post("/employees")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(newEmployee)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.id").exists())
.andExpect(jsonPath("$.email").value("new.employee@example.com"));
}
@Test
void createEmployee_ShouldReturnValidationErrors() throws Exception {
EmployeeDto invalidEmployee = EmployeeDto.builder().build();
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/employees")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(invalidEmployee)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.firstName").value(containsString("First name is required")))
.andExpect(jsonPath("$.email").value(containsString("Email is required")))
.andExpect(jsonPath("$.employmentType").value(containsString("Employment type is required")))
.andExpect(jsonPath("$.emergencyContact").value(containsString("Emergency contact is required")))
.andExpect(jsonPath("$.jobTitle").value(containsString("Job title is required")))
.andExpect(jsonPath("$.department").value(containsString("Department is required")))
.andExpect(jsonPath("$.phoneNo").value(containsString("Phone number is required")))
.andReturn();
}
@Test
void updateEmployee_ShouldUpdateExistingEmployee() throws Exception {
EmployeeDto updateDto = TestDataFactory.buildTestEmployeeDtoWithFullData();
updateDto.setFirstName("UpdatedFirstName");
updateDto.setLastName("UpdatedLastName");
mockMvc.perform(MockMvcRequestBuilders.put("/employees/{id}", existingEmployee.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(updateDto)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.firstName").value("UpdatedFirstName"))
.andExpect(jsonPath("$.lastName").value("UpdatedLastName"));
}
@Test
void updateEmployee_ShouldReturn404ForNonExistingId() throws Exception {
EmployeeDto updateDto = TestDataFactory.buildTestEmployeeDtoWithFullData();
mockMvc.perform(MockMvcRequestBuilders.put("/employees/9999")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(updateDto)))
.andExpect(status().isNotFound());
}
@Test
void deleteEmployee_ShouldReturnNoContent() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.delete("/employees/{id}", existingEmployee.getId()))
.andExpect(status().isNoContent());
}
@Test
void deleteEmployee_ShouldReturn404ForNonExistingId() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.delete("/employees/9999"))
.andExpect(status().isNoContent());
}
@Test
void getAllEmployees_ShouldReturnEmptyListWhenNoRecords() throws Exception {
// Delete the existing employee
mockMvc.perform(MockMvcRequestBuilders.delete("/employees/{id}", existingEmployee.getId()))
.andExpect(status().isNoContent());
// Verify that no employees exist
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/employees")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
EmployeeResponse<Employee> response = objectMapper.readValue(
result.getResponse().getContentAsString(),
new com.fasterxml.jackson.core.type.TypeReference<>() {
});
assertThat(response.getData()).isEmpty();
assertThat(response.getPagination().getTotalResults()).isZero();
}}
Annotations explained:
- @SpringBootTest: Loads the full application context (suitable for integration testing).
- @AutoConfigureMockMvc: Automatically configures MockMvc, allowing you to perform HTTP request simulations.
- @BeforeEach: Runs before each test to set up common test data.
- @Test: Marks a method as a test case.
- @MockBean: (In some tests) Creates a mock for the service layer to isolate the controller testing.
EmployeeServiceTest.java
package com.employee.service;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import com.employee.common.mapper.EmployeeMapper;
import com.employee.dao.Employee;
import com.employee.dto.EmployeeDto;
import com.employee.exception.EmployeeException;
import com.employee.repository.EmployeeRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@ExtendWith(MockitoExtension.class)
class EmployeeServiceTest {
@Mock
private EmployeeRepository employeeRepository;
@Mock
private EmployeeMapper employeeMapper;
@InjectMocks
private EmployeeService employeeService;
private EmployeeDto employeeDto;
private Employee employee;
@BeforeEach
void setUp() {
employeeDto = new EmployeeDto();
employeeDto.setId(1L);
employeeDto.setFirstName("John");
employeeDto.setLastName("Doe");
employeeDto.setEmail("john.doe@example.com");
employeeDto.setPhoneNo("+1234567890");
employeeDto.setJobTitle("Software Engineer");
employeeDto.setDepartment("IT");
employeeDto.setDateOfJoining(LocalDate.now());
employeeDto.setEmploymentType("Full-Time");
employeeDto.setEmergencyContact("+9876543210");
employee = new Employee();
employee.setId(1L);
// Set other fields similarly
}
@Test
void testGetEmployee() {
when(employeeRepository.findById(1L)).thenReturn(Optional.of(employee));
Employee result = employeeService.getEmployee(1L);
assertNotNull(result);
assertEquals(1L, result.getId());
}
@Test
void testGetEmployeeNotFound() {
when(employeeRepository.findById(1L)).thenReturn(Optional.empty());
assertThrows(EmployeeException.class, () -> employeeService.getEmployee(1L));
}
@Test
void testSaveEmployee() {
when(employeeMapper.EmployeeDtoToDao(employeeDto)).thenReturn(employee);
when(employeeRepository.save(employee)).thenReturn(employee);
Employee result = employeeService.saveEmployee(employeeDto);
assertNotNull(result);
assertEquals(1L, result.getId());
}
@Test
void testFindTeamWithPagination() {
Page<Employee> page = new PageImpl<>(Arrays.asList(employee));
when(employeeRepository.findAll(any(PageRequest.class))).thenReturn(page);
Page<Employee> result = employeeService.findTeamWithPagination(0, 10, "id", Sort.Direction.ASC);
assertNotNull(result);
assertEquals(1, result.getTotalElements());
}
@Test
void testFindEmployeeById() {
when(employeeRepository.findById(1L)).thenReturn(Optional.of(employee));
Employee result = employeeService.findEmployeeById(1L);
assertNotNull(result);
assertEquals(1L, result.getId());
}
@Test
void testFindEmployeeByIdNotFound() {
when(employeeRepository.findById(1L)).thenReturn(Optional.empty());
assertThrows(EmployeeException.class, () -> employeeService.findEmployeeById(1L));
}
@Test
void testDeleteEmployeeById() {
doNothing().when(employeeRepository).deleteById(1L);
assertDoesNotThrow(() -> employeeService.deleteEmployeeById(1L));
verify(employeeRepository, times(1)).deleteById(1L);
}
@Test
void testUpdateEmployee() {
when(employeeRepository.findById(1L)).thenReturn(Optional.of(employee));
when(employeeRepository.save(employee)).thenReturn(employee);
Employee result = employeeService.updateEmployee(1L, employeeDto);
assertNotNull(result);
assertEquals(1L, result.getId());
verify(employeeMapper, times(1)).updateEmployeeFromDto(employeeDto, employee);
}
@Test
void testUpdateEmployeeNotFound() {
when(employeeRepository.findById(1L)).thenReturn(Optional.empty());
Employee result = employeeService.updateEmployee(1L, employeeDto);
assertNull(result);
}
}
Annotations explained:
- @ExtendWith(MockitoExtension.class): Enables Mockito support for JUnit 5.
- @Mock: Creates mock objects for dependencies.
- @InjectMocks: Injects the mock objects into the tested service.
- @BeforeEach: Prepares common test data before each test.
- @Test: Marks each method as a test case.
- The tests verify positive flows (employee found, save, update) and negative flows (employee not found) using assertions.
In src/test/resources/application.yml, configure the H2 test database and JPA settings:
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: create-drop
Explanation:
- The H2 URL uses an in-memory database for testing.
- ddl-auto: create-drop ensures that the schema is created at startup and dropped at shutdown.
Write a Docker file to run a Spring Boot application:
FROM openjdk:17-jdk-slim
COPY target/employee-0.0.1-SNAPSHOT.jar employee.jar
ENTRYPOINT ["java", "-jar", "employee.jar"]
Build your Docker image:
docker build -t employee-app .
Run the container:
docker run -p 8080:8080 employee-app7.2 Kubernetes Deployment
Create a deployment.yaml file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: employee-app-deployment
spec:
replicas: 1
selector:
matchLabels:
app: employee-app
template:
metadata:
labels:
app: employee-app
spec:
containers:
- name: employee-app-container
image: your-dockerhub-username/employee-app:latest # Replace with your Docker image
ports:
- containerPort: 8080
volumeMounts:
- name: h2-storage-volume
mountPath: /data/h2
volumes:
- name: h2-storage-volume
persistentVolumeClaim:
claimName: h2-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: h2-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: employee-app-service
spec:
selector:
app: employee-app
ports:
- protocol: TCP
port: 8080
targetPort: 8080
Deploy using:
kubectl apply -f deployment.yaml
By understanding each layer — from the main application class to controller, service, DTO, mapper, repository, and exception handling — and by writing well-structured tests (both integration and unit tests), you’re now ready to build robust, production-ready applications.
The github link here.
Thank you for reading this article. Please provide your valuable suggestions/ feedback.
- Clap and Share if you liked the content.
- 📰 Read more content on my Medium (on Java Developer interview questions)
- 🔔 Follow me on: LinkedIn
Please find my other useful articles on Java Developer interview questions
Following are some of the famously asked Java8 Interview Questions
Frequently asked Java Programs
Dear Readers, these are the commonly asked java programs to check your ability on writing the logic
SpringBoot Interview Questions | Medium
Rest and Microservices Interview Questions| Medium
♦A Complete Guide to Build, Test and Deploy a Spring Boot Application was originally published in Code Like A Girl on Medium, where people are continuing the conversation by highlighting and responding to this story.
Code Like a Girl
Stability Is Overrated: Why I Changed My “Perfect” Team?
♦
Trading stability for stretch goals and soul-searching.
Continue reading on Code Like A Girl »